简体   繁体   中英

bash scripting and conditional statements

I am trying to run a simple bash script but I am struggling on how to incoperate a condition. any pointers. the loop says. I would like to incoperate a conditions such that when gdalinfo cannot open the image it copies that particular file to another location.

for file in `cat path.txt`; do gdalinfo $file;done

works fine in opening the images and also shows which ones cannot be opened.
the wrong code is

for file in `cat path.txt`; do gdalinfo $file && echo $file; else cp $file /data/temp

Again, and again and again - zilion th again...

Don't use contsructions like

for file in `cat path.txt`

or

for file in `find .....`
for file in `any command what produces filenames`

Because the code will BREAK immediatelly, when the filename or path contains space. Never use it for any command what produces filenames. Bad practice. Very Bad. It is incorrect, mistaken, erroneous, inaccurate, inexact, imprecise, faulty, WRONG.

The correct form is:

for file in some/*   #if want/can use filenames directly from the filesystem

or

find . -print0 | while IFS= read -r -d '' file

or (if you sure than no filename contains a newline) can use

cat path.txt | while read -r file

but here the cat is useless, (really - command what only copies a file to STDOUT is useless). You should use instead

while read -r file
do
   #whatever
done < path.txt

It is faster (doesn't fork a new process, as do in case of every pipe).

The above while s will fill the corect filename into the variable file in cases when the filename contains a space too. The for will not . Period. Uff. Omg.

And use "$variable_with_filename" instead of pure $variable_with_filename for the same reason. If the filename contains a white-space any command will misunderstand it as two filenames. This probably not, what you want too..

So, enclose any shell variable what contain a filename with double quotes. (not only filename, but anything what can contain a space). "$variable" is correct.

If i understand right, you want copy files to /data/temp when the gdalinfo returns error.

while read -r file
do
   gdalinfo "$file" || cp "$file" /data/temp
done < path.txt

Nice, short and safe (at least if your path.txt really contains one filename per line).

And maybe, you want use your script more times, therefore dont out the filename inside, but save the script in a form

while read -r file
do
   gdalinfo "$file" || cp "$file" /data/temp
done

and use it like:

mygdalinfo < path.txt

more universal...

and maybe, you want only show the filenames for what gdalinfo returns error

while read -r file
do
   gdalinfo "$file" || printf "$file\n"
done

and if you change the printf "$file\\n" to printf "$file\\0" you can use the script in a pipe safely, so:

while read -r file
do
   gdalinfo "$file" || printf "$file\0"
done

and use it for example as:

 mygdalinfo < path.txt | xargs -0 -J% mv % /tmp/somewhere

Howgh.

You can say:

for file in `cat path.txt`; do gdalinfo $file || cp $file /data/temp; done

This would copy the file to /data/temp if gdalinfo cannot open the image.

If you want to print the filename in addition to copying it in case of failure, say:

for file in `cat path.txt`; do gdalinfo $file || (echo $file && cp $file /data/temp); done

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM