简体   繁体   中英

remove file starting with space in shell scripting

I'm trying to write a shell script to cleanup a directory by deleting files that match particular patterns. My code works with all patterns but if the file name starts with space. Although we can delete a file starting with space by rm \\ * however if I pass this pattern to my script it won't delete files starting with space. Here is my code:

  for file in *;do         
    for pattern in $*; do  
      if [[ -f "$file" && "$file" == $pattern ]]; then    
       rm "$file"  
      fi 
    done   
  done

I also tried this simpler code, but the same problem!

for pattern in $*; do    
  if [[ -f $pattern ]]; then   
    rm $pattern
  fi
done

Could you please help me why there is a problem just with files starting with space?!

Rather than $* , if you use the special parameter $@ , the items in the list will start with quotes around them. You still have to quote the variables where you use them.

Reworking the second example, that would be

for pattern in "$@"; do    
  if [[ -f "$pattern" ]]; then   
    rm -f "$pattern"
  fi
done

this is really a challenging one for starters please see below example

[shravan@localhost mydir]$ ls " myfile"
 myfile
[shravan@localhost mydir]$ echo $vr1
" myfile"
[shravan@localhost mydir]$ ls $vr1
ls: ": No such file or directory
ls: myfile": No such file or directory
[shravan@localhost mydir]$ vr2=" myfile"
[shravan@localhost mydir]$ echo $vr2
myfile

You can see above that ls " myfile" is working but it is not working after assigning this value in variable vr1 or vr2. So we cannot do check of file if it exists or not.

For solution keep all you patterns in a file and all patterns in double quotes. see example below.

[shravan@localhost mydir]$ touch " myfile"
[shravan@localhost mydir]$ touch my.pl
[shravan@localhost mydir]$ ls
exe.sh  findrm  inp  input   myfile  my.pl  pattern  text  text1
[shravan@localhost mydir]$ cat inp
" myfile"
"my.pl"
[shravan@localhost mydir]$ cat inp | xargs rm
[shravan@localhost mydir]$ ls
exe.sh  findrm  inp  input  pattern  text  text1

The files are removed. Or if you have lot of patterns and dont want to add quotes to them use below.

 cat inp | awk '{print "\""$0"\""}' | xargs rm

Yes if file is not found then it will give error for that file that

rm: cannot remove ` myfile': No such file or directory
for file in *;do         
  for pattern in "$@"; do  
    if [[ -f "$file" && "$file" == $pattern ]]; then    
     rm "$file"  
     fi 
  done   
done

If we simply change $@ to quoted "$@" then each individual argument would be wrapped in double quotation and no space would be lost. On the other hand we need a quoted string at the right of == operator, because when the '==' operator is used inside [[ ]], the string to the right of the operator is considered a pattern. But here we will not quote $pattern since all arguments in the list include double quotation.

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