0

I'm having a problem with my code in bash.

I want my code to check if a file exists on a directory, but since the file will be constantly changing his name, I want to search for his "extension".

So basicly when I start my script, it will check if a directory exists or not, if it doesent it will create it, then I want to check if there is any file starting with a "." (dot) in that directory, if it doesent exist it will create an empty file called ".200"

Here is the code.

#!/bin/bash

directory=$HOME/.impressora
mkdir -p $directory
if [ ! -f "$directory/.*" ]
then echo "" > $directory/.200

the thing is that, after this, I am adding a bunch of code that will keep changing the name of that file, for example, it will go from ".200" , to ".199", to ".198" , to ".197" etc...

So in my "If" statement I have to search if the directory has any file starting with a "." (dot).

I have already used the commands "shopt -s dotglob" and "shopt -u dotglob" to make him ignore the "." and ".." files, puten by default in that directory.

I tried to test this by adding a variable called "file" and try to make it have the value of the extension of the ".200" file and then printing it, but the value that is stored in that variable is ".*" and not "200" has I wanted... Here is the code with the variable.

Directory=$HOME/.impressora
file=$HOME/.impressora/.*
echo "$file"
mkdir -p $directory
if [ ! -f "$directory/.*" ]
then echo "" > $directory/.200
fi

I hope you can help me out, I have been desperately trying to solve this... Thank you.

MSU_Bulldog
  • 3,501
  • 5
  • 37
  • 73
  • Your test (the [ ...] part) isn't syntactically valid if the .* part matches no files or more than one file. – LinuxDisciple Mar 28 '16 at 20:31
  • Also the preceding '.' char in the name is a Linux(/Unix?) convention for hidden files, which Bash won't show by default. That's why your ".*" isn't expanding to include your 'hidden' file .200. – LinuxDisciple Mar 28 '16 at 20:41
  • 1
    @LinuxDisciple That's not why. The glob pattern isn't being expanded because bash doesn't do glob expansion inside quoted strings. – Mike Holt Mar 28 '16 at 20:45
  • So how can i make it work? – Vasco Pereira Mar 28 '16 at 20:48
  • Possible duplicate questions: http://stackoverflow.com/questions/2937407/test-whether-a-glob-has-any-matches-in-bash and http://stackoverflow.com/questions/6363441/check-if-a-file-exists-with-wildcard-in-shell-script. – Mike Holt Mar 28 '16 at 20:49
  • @VascoPereira See the other StackOverflow questions I listed as possible duplicates. I'm pretty sure you'll find a solution there. Between those two, there are several solutions given. – Mike Holt Mar 28 '16 at 20:53

4 Answers4

0

You might pipe a find command to grep, which can use regular expressions. This command will tell you how many files in a directory start with a period and include at least one number (and no letters):

find testing/  -printf "%f\n" | grep -c '\.[0-9]\+$'

You can then check on the grep result to see if it's greater than 0.

(Depending on your version of "find," you might also be able to use regular expressions directly in the find command. Another caveat: Needing to escape that +, and not escaping the $, might vary depending on your OS.)

Community
  • 1
  • 1
rabdill
  • 449
  • 1
  • 7
  • 11
0

You could record the inode of the file when it's first created. The inode will not change when the file is renamed:

#!/bin/bash

directory=$HOME/.impressora
if [ ! -d "$directory" ]; then
    # create the directory and create the initial file
    mkdir -p $directory
    touch $directory/.200

    # record the file's inode
    stat --format=%i $directory/.200 > $directory/.inode
fi

# retrieve the file's path using its inode value
filepath=$(find $directory -inum $(cat $directory/.inode))
echo "\$filepath: $filepath"

Try renaming $directory/.200 and run this script again to verify the file can be found using its inode.

Cole Tierney
  • 9,571
  • 1
  • 27
  • 35
0

so ive been trying to understand and experiment with the solutions you guys gave me, but has i told you i am really noob at shell scripting so i couldn't implement the solutions you guys kindly gave me. So let me try to break down my code in simple human lenguage and hopefully you could help me turn it in to shell lenguage. I will coment every line of code not because i dont expect you to understand what it does, but because what i think it will do may be diferent from what it will really do xD. I dont know if my english is correct but sorry if im being confusing.

So here it goes.

!#/bin/bash

directory=$HOME/.impressora
# stores the path $HOME/.impressora in the variable directory

cred=0

mkdir -p $directory
# check if the path $HOME/.impressora exists, if it doesen't create it

if [ ! -f "$directory/.*" ]
#now at this part i want the script to create a file called ".200" if 
#there is no other file started by a "." (dot) in that directory
#i cannot put a specific file name because when i run this script for the
#first time on a fresh computer i want it to create a .200 file wich,
#afterwards will be renamed over and over again

then echo "" > $directory/.200
# so if there is no file started by a "." (dot) on that directory,
#create a file called ".200"
fi

creditos=$(echo $directory/.* | cut -c7-)
#now i want to set the variable creditos = to the name of the file in the
#directory we just created but without the "." (dot).
#so the first time this program runs i want creditos to be = to 200
#but then when i change the name of the file to ".199" i want the variable
#creditos to be = to 199 and so on...

if [ $1 = "lp" ]
#now this script is called "project" so if i type "./project lp" 
#in the terminal do...

then
if [ -d $directory ] && [ $creditos > 0 ]
#if the directory exists and the variable "creditos" is grater than 0...

then
    echo "" > $directory/lp-$imp
    #create an empty file called "lp-the value of a varable wich needs to
    #increment by 1 each time i run the command "./project lp"
    #this is another thing i dont know how to do, how do i implement a
    #variable in wich her value is persistent?
    #the objective is, each time i type "./project lp" in the console
    #if the directory exists and the variable creditos is greater than 0
    #create a file called "lp-1", "lp-2" , "lp-3" and so on

    $cred=$creditos
    # on the first usage of the script "$cred" = 200
    ((cred--))

    mv $directory/.$creditos $directory/.$cred
    #this is my way to rename the file, so it would go from ".200"
    #to ".199" and so on
else
    echo "Diretorio inexistente ou creditos insuficientes"
    #if the directory doesent exist or the variable creditos
    #is lower than 200, print that message
fi
fi

Sorry for the bunch of text, but i dont have a better way to exactly explain what i need, i hope you can help me out! Thanks alot for your time!

0

As the file as no name (because it starts with a dot) it's automatically the first file to appear at your directory is that one. So first you need to "ls -a" your dir. Next you need to jump the two "files" that appear which are the:

.

and

..

So, you do the "head -3" command so you can select the 3 first lines (files) of the folder. Next you need to select the last one of those 3 so you pipe it again and do the "tail -1"

Finally you need to remove the dot in the .200 file so you can save only the value to the var, to do this you have to pipe "cut -f2 -d".""

Basicly you need to replace the

creditos=$(echo $directory/.* | cut -c7-)

with

creditos=$(ls -a $directory | head -3 | tail -1 | cut -f2 -d".")