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
2
  • Using the bash shell gives the expected output. I suspect you are using a different shell.
    – fpmurphy
    Commented Jul 7, 2017 at 2:58
  • Double-quote your variables when you use them. For example, "$output" instead of plain $output. Commented Jul 7, 2017 at 23:09

3 Answers 3

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
1
  • ./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. :( Commented Jul 7, 2017 at 3:05
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.

0
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
2
  • The else part should be echo "$output".
    – NickD
    Commented Jul 7, 2017 at 3:39
  • It only prints the content of fnames.txt which is $LINE. Commented Jul 7, 2017 at 5:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .