Logical OR in my shell script

My script:

#!/bin/bash for file in *.ats; do if [[ ("${file}" = THx) || ("${file}" = THy)]] then cp $file /home/milenko/procmt fi done 

Files in the directory

 262_V01_C00_R000_TEx_BL_128H.ats 262_V01_C01_R000_TEy_BL_128H.ats 262_V01_C02_R000_THx_BL_128H.ats 262_V01_C03_R000_THy_BL_128H.ats 

I would like to copy files containing thanks or THy, but the files are not copied. Why?

+5
source share
4 answers

How about using extglob for advanced fit? Thus, you can use for to get the necessary extensions:

 shopt -s extglob for file in *TH?(x|y)*.ats; do # do things with "$file" ... done 

*TH?(x|y)*.ats expands to those files containing <something> + TH + either x or y + <something> + .ats


Your script fails because it has a typo in it :

 if [[ ("${file}" = THx) || ("${file}" = THy)]] # ^ # missing space 

This is normal:

 $ d="hi" $ [[ ($d == hi) || ($d == ha) ]] && echo "yes" yes 

Although the brackets are redundant:

 $ [[ $d == hi || $d == ha ]] && echo "yes" yes 
+4
source

I think you can completely avoid the loop:

 cp *TH[xy]*.ats /home/milenko/procmt 

There is no need to iterate over the results and then perform a separate comparison; one globe will expand to the list of files you want.

There were a couple of problems with your original approach:

  • First, you tried to verify exact matches, so the condition will never be true.
  • Also, be careful with spaces: ]] is a keyword in the compound command [[ , so it should be a separate word (i.e. surrounded by spaces).
+9
source

Your question says "files containing thanks or THy" ... but your code indicates that the file name thanks or thy.

+5
source

You can use the character class in glob ie *TH[xy]* to check if $file THx or THy :

 for file in *.ats; do if [[ $file == *TH[xy]* ]]; then cp "$file" /home/milenko/procmt fi done 
+4
source

All Articles