Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple Bash - for f in *

Consider this simple loop:

for f in *.{text,txt}; do echo $f; done

I want to echo ONLY valid file names. Using the $f variable in a script everything works great unless there aren't any files of that extension. In the case of an empty set, $f is set to *.text and the above line echos:

*.text
*.txt

rather than echoing nothing. This creates an error if you are trying to use $f for anything that is expecting an actual real file name and instead gets *.

If there are any files that match the wildcard so that it is not an empty set everything works as I would like. e.g.

123.text
456.txt
789.txt

How can I do this without the errors and without seemingly excessive complexity of first string matching $f for an asterisk?

like image 558
user1610022 Avatar asked Sep 07 '12 14:09

user1610022


People also ask

What does * represent in bash?

If you see $ in prefix with anything , it means its a variable. The value of the variable is used. Example: count=100 echo $count echo "Count Value = $count" Output of the above script: 100 Count Value = 100.

What does $() mean bash?

Example of command substitution using $() in Linux: Again, $() is a command substitution which means that it “reassigns the output of a command or even multiple commands; it literally plugs the command output into another context” (Source).

What does $# in bash mean?

$# is a special variable in bash , that expands to the number of arguments (positional parameters) i.e. $1, $2 ... passed to the script in question or the shell in case of argument directly passed to the shell e.g. in bash -c '...' .... .

What does [- Z $1 mean in bash?

$1 means an input argument and -z means non-defined or empty. You're testing whether an input argument to the script was defined when running the script. Follow this answer to receive notifications.


2 Answers

You can test if the file actually exists:

for f in *.{text,txt}; do if [ -f $f ]; then echo $f; fi; done

or you can use the find command:

for f in $(find -name '*.text' -o -name '*.txt'); do
  echo $f
done
like image 182
perreal Avatar answered Oct 25 '22 01:10

perreal


Set the nullglob option.

$ for f in *.foo ; do echo "$f" ; done
*.foo
$ shopt -s nullglob
$ for f in *.foo ; do echo "$f" ; done
$ 
like image 42
Ignacio Vazquez-Abrams Avatar answered Oct 25 '22 01:10

Ignacio Vazquez-Abrams