21

I have a bunch of output files in a directory, such as: a.out, b.out c.out, etc.

I want to search through the output files and if the output file name contains a certain string (such as "a"), then it will print the corresponding output file "a.out" to screen.

After I cd-ed into the output files directory, here's my code:

OUT_FILE="*.out"
OT=$OUT_FILE
STRING="a"

for file in "$OT";do
  if [[$file == *"$STRING"*]];then
    echo $file
  fi
done

The error I received is [[*.out: command not found. It looks like $file is interpreted as $OT, not as individual files that matches $OT.

But when I removed the if statement and just did a for-loop to echo each $file, the output gave me all the files that ended with .out.

Would love some help to understand what I did wrong. Thanks in advance.

3
  • 6
    shellcheck.net Commented May 13, 2018 at 22:56
  • 3
    Wildcards (like *.out) aren't expanded inside double-quotes or on the right side of an assignment, so yours never gets converted to a list of files (until you echo it without double-quotes). Also, you need spaces between [[, the elements of the comparison, and ]]. Spaces are critical delimiters in the shell; do not leave them out. Commented May 13, 2018 at 23:14
  • 2
    Space -- the final frontier. Commented May 14, 2018 at 8:52

2 Answers 2

25

You need space after [[ and before ]]:

for file in *.out;do
  if [[ "$file" == *"$STRING"* ]];then
    printf '%s\n' "$file"
  fi
done

or just

for file in *"$STRING"*.out; do
    printf '%s\n' "$file"
done

or

printf '%s\n' *"$STRING"*.out
Sign up to request clarification or add additional context in comments.

7 Comments

Could you explain what is '%s\n? Thanks!
@katiayx %s is the printf format specifier for "a string". The %s acts like a placeholder for the next argument on the command line. The value of the next argument will replace %s in the output. The \n will be replaced by a newline. If printf is given more argument than placeholders in the format string, the format string will be reused.
@Kusalananda We need to check for particular directory also, Where we can mention directory path
@BhageshArora If the directory path is in DIRPATH, then use for file in "$DIRPATH"/*"$STRING"*.out; do ...; done.
@Kusalananda Not working propery, cursor is going in both if and else condition. Inside the for loop.
|
7

Without bashisms like [[ (works in any Bourne-heritage shell) and blindingly fast since it does not fork any utility program:

for file in *.out; do
  case $file in
    (*a*) printf '%s\n' "$file";;
  esac
done

If you want you can replace (*a*) with (*$STRING*).

Alternative if you have a find that understands -maxdepth 1:

find . -maxdepth 1 -name \*"$STRING"\*.out

PS: Your question is a bit unclear. The code you posted tests for a in the file name (and so does my code). But your text suggests you want to search for a in the file contents. Which is it? Can you clarify?

2 Comments

My goal is to search for a in the file name. Sorry for the confusion.
@katiayx Then the easiest is probably for i in *"$STRING"*.out; do echo "$i"; done, assuming there is at least one match.

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.