0

I would like to echo something from an output of a command that returns nothing.

This is the content of fnames.txt

company_TOYOTA_666_696969696*
company_FORD_123_435345666*
company_MAZDA_333_333333333*
company_HONDA_777_777777777*
company_FERARI_999_999999999*

This is my script to find each files in a line from fnames.txt:

#!/bin/sh

while read -r LINE
do
    output=$(find . -name "$LINE")

    if [[ $output ]];
    then
            printf "$output\n"
    elif [[ $output -eq 0 ]];
    then
            echo "$LINE Not Found"
    fi
done < /path/to/fnames.txt

But when I try to execute it, it only outputs the files it found not the elif statement that echo's the filename it didn't find:

./company_TOYOTA_666_696969696_11_22_33_4542352345.dat
./company_FORD_123_435345666_11_22_33_4542352345.dat
./company_MAZDA_333_333333333_11_22_33_4542352345.dat
./company_HONDA_777_777777777_11_22_33_4542352345.dat

I would like it to output this:

./company_TOYOTA_666_696969696_11_22_33_4542352345.dat
./company_FORD_123_435345666_11_22_33_4542352345.dat
./company_MAZDA_333_333333333_11_22_33_4542352345.dat
./company_HONDA_777_777777777_11_22_33_4542352345.dat
company_FERARI_999_999999999* Not Found
  • Using the bash shell gives the expected output. I suspect you are using a different shell. – fpmurphy Jul 7 '17 at 2:58
  • Double-quote your variables when you use them. For example, "$output" instead of plain $output. – roaima Jul 7 '17 at 23:09
2

I would recommend leveraging grep and return codes to make life a little simpler.

while read -r LINE
do
    find . -name "${LINE}" | grep "${LINE}" || echo "${LINE} not found"

done < /path/to/fnames.txt

How this works:

  • find . -name "${LINE}" pretty sure you know this one, find files in current directory that match ${LINE}
  • | grep "${LINE}" pipe the output to grep. We do this to produce a return value, which find does not normally produce a useful one. If the grep matches something, the match will be printed and the command returns 0. If nothing is matched, nothing is printed and it returns a non-zero return value.

  • || echo "${LINE} not found" The || is an OR pipe, if one of the commands before it returns non-zero it will be performed. So if the grep returns non-zero (i.e. no matching files were found) this echo is performed. If the commands before it succeed it will not be performed.

3

You can use the -z and -n string test operators:

String operators:

  -z STRING      True if string is empty.

  -n STRING
     STRING      True if string is not empty.

e.g.

while read -r LINE; do 
  output=$(find . -name "$LINE")
  if [[ -z "$output" ]]; then 
    echo "$LINE not found"
  else 
    echo "$output"
  fi
done < fnames.txt 
company_TOYOTA_666_696969696* not found
./company_FORD_123_435345666asdfgh
company_MAZDA_333_333333333* not found
./company_HONDA_777_7777777771242jkk
company_FERARI_999_999999999* not found

where

$ ls -1 company*
company_FORD_123_435345666asdfgh
company_HONDA_777_7777777771242jkk
  • ./company_TOYOTA_666_696969696_11_22_33_4542352345.dat company_FERARI_999_999999999* Not Found ./company_FORD_123_435345666_11_22_33_4542352345.dat company_FERARI_999_999999999* Not Found ./company_MAZDA_333_333333333_11_22_33_4542352345.dat company_FERARI_999_999999999* Not Found ./company_HONDA_777_777777777_11_22_33_4542352345.dat company_FERARI_999_999999999* Not Found This is the output. Not the result I'm looking for. :( – WashichawbachaW Jul 7 '17 at 3:05
0
#!/bin/bash

while read -r LINE
do
    output=$(find . -name "$LINE" 2> /dev/null)

    if [[ -z $output ]]; then
        echo  "$LINE Not Found"
    else
        echo  "$output"
    fi
done < /path/to/fnames.txt
  • The else part should be echo "$output". – NickD Jul 7 '17 at 3:39
  • It only prints the content of fnames.txt which is $LINE. – WashichawbachaW Jul 7 '17 at 5:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.