0
#!/bin/bash

echo "Enter the search string"
read str

for i in `ls -ltr | grep $str  > filter123.txt ; awk '{ print $9 }' filter123.txt` ; do

if [ $i != "username_list.txt" || $i != "user_list.txt" ] ; then

else
 rm $i
fi
done

I'm a beginner of unix shell scritping, i create above file for delete file based on given string using grep method. while i executing above script file it showing error like "./rm_file.txt: line 10: syntax error near unexpected token `else' ". please suggested what's the error in this script.

2
  • 1
    Why are you using grep and awk and a temporary file? Just do ls -ltr | awk "/$str/{print \$9}" (This will fail if str contains certain characters, but so does grep $str) Commented Jan 7, 2014 at 13:02
  • Use [[]] (see mywiki.wooledge.org/BashPitfalls#A.5B_.24foo_.3D_.22bar.22_.5D). Also not sure why you're trying if !a || !b then nothing else something instead of the logically equivalent if a && b then something. Commented Jan 7, 2014 at 14:01

4 Answers 4

3

There are several problems with your code:

  1. Don't parse the output of ls. Although it may work much of the time, it will break for certain file names, and there are safer alternatives.

  2. Replace filter123.txt with another pipe.

  3. You can negate the exit status of the condition, so that you don't need an else clause.

  4. Your if condition is always true, since any file name will be unequal to one of the two options. You probably mean to use &&.

  5. || and && are not available inside [ ... ]. Either use two [ ... ] commands or use [[ ... ]].

Addressing the items above:

for i in *$str*; do
    if [[ $i != username_list.txt && $i = user_list.txt ]]; then
        rm "$i"
    fi
done
Sign up to request clarification or add additional context in comments.

Comments

1

To use a boolean operator with [, you can use one of:

if [ "$i" != username_list.txt ] && [ "$i" != user_list.txt ] ; then ...
if [ "$i" != username_list.txt -a "$i" != user_list.txt; then ...

But in this case, it is probably cleaner to use a case statment:

case "$i" in
username_list.txt|user_list.txt) : ;;
*) rm "$i";;
esac

Comments

1

between then and else there is nothing, if you want do nothing, you can put : there

to delete files in current director with certain string in the name, you can use find

#!/bin/bash
read -p "Enter the search string: " str

# to exclude "username_list.txt" and "user_list.txt"
find . -maxdepth 1 -type f -name "*$str*" -a -not \( -name "username_list.txt" -o -name "user_list.txt" \) | xargs -I'{}' ls {}

Comments

1

It can also be done with find:

find . -maxdepth 1 -type f -name "*$str*" ! -name username_list.txt ! -name user_list.txt -exec rm {} \;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.