0

I want to find a file. If user input "file.txt", then I need to echo the "file.txt". But if file name not found, just echo "not found". The code i have is for finding a word in a file. But how if I just need to search the file. If I write : result=`grep $filename`, it won't work. What's the format for grep filename?

 #!/bin/bash
    echo -n "File name : "
    read filename
    echo -n "Word : "
    read word
    result=`grep $word $filename`
    if [ "$result" != "" ]
    then
          echo "$result"
    else
          echo "Not found"
    fi
Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
ilovecode
  • 35
  • 4
  • I don't think I understand – do you want to check if a given file exists? – Benjamin W. Jun 02 '21 at 14:11
  • 3
    Why do you need to use `grep`? Using `if [ -f "$filename" ]; then echo "$filename"; else echo "not found"; fi` would do what you want. – Jonathan Leffler Jun 02 '21 at 14:11
  • yes that's right @BenjaminW. – ilovecode Jun 02 '21 at 14:24
  • umm but is it possible if i need to use grep? @JonathanLeffler – ilovecode Jun 02 '21 at 14:25
  • 2 inputs are taken. Do you want to find the input word exists in the input file? – abhishek phukan Jun 02 '21 at 14:25
  • 2
    How many different ways do you want to do it? Yes, you can use `grep`; no, there isn't any point in doing so, and any such use of `grep` is pretty much pointless (not to mention a lot harder than doing it the sane way). I suppose you could try some variant on `ls "$filename" 2>/dev/null | grep "$filename" || echo "not found"`. But using the output of `ls` like that is subject to error if your file names could contain newlines, spaces, or other non-recommended characters. – Jonathan Leffler Jun 02 '21 at 14:39
  • 1
    [POSIX](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html) specifies that grep returns with exitcode >1 on error – jhnc Jun 02 '21 at 14:56
  • I’m voting to close this question because Stack Overflow is explicitly scoped to _practical_, answerable questions; and using `grep` for a job that `test -f` is better suited for is innately impractical. – Charles Duffy Jun 02 '21 at 18:02
  • Technically, the test is for a file with the value in it, so `grep -l` does the job in fewer programmatic steps, if not less actual work... – Paul Hodges Jun 02 '21 at 19:36
  • It seem to me that you find a code with grep and you try to resolve your problem withi it. I thi,k there is not the good tool but you try nothing and wait for someone to give you the solution.. No seach from your side ! – ctac_ Jun 02 '21 at 20:20

3 Answers3

0

It looks like you are trying to determine if $word is present in $filename. If so:

if ! grep "$word" "$filename"; then
   echo not found >&2
fi

The check to determine if the file exists seems redundant, since grep will emit an error message if the file does not exist, but perhaps you want something like:

if test -e "$filename" && ! grep "$word" "$filename"; then
    echo "$word" is not found in "$filename" >&2
else
    echo "$filename" does not exist >&2
fi

which will not print the redundant "not found" in addition to the error message from grep saying that the file does not exist.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
0

With grep, you can try this way :

#!/bin/bash
OLDIFS="$IFS"
IFS=''
read -p "File name : " filename
IFS=$OLDIFS
grep -l '' "$filename" 2>/dev/null
! [ $? -eq 0 ] && echo "file $filename not found"

bemol : grep do not find a file with a size of 0.

ctac_
  • 2,413
  • 2
  • 7
  • 17
  • 1
    If you want to set IFS only for the `read`, just put it on the same line with no `;` or other command separator: `IFS= read -r -p "File name : " filename`, and then the change is scoped to the `read` so you don't need to change it back later. – Charles Duffy Jun 02 '21 at 17:57
  • 3
    Also, using `$?` this way is generally an antipattern. I don't know why you'd ever want to do it, instead of `grep -q -l "" "$filename" &>/dev/null || echo "file $filename not found" >&2`. See [Why is testing `$?` to see if a command succeeded or not an antipattern?](https://stackoverflow.com/questions/36313216/why-is-testing-to-see-if-a-command-succeeded-or-not-an-anti-pattern) – Charles Duffy Jun 02 '21 at 17:58
  • @CharlesDuffy. Thanks for comments.The OP want to print the filename if the file exist and not found if the file don't exist so the -q option is not needed. I must study your comment before update the answer because I don't understand the &>/dev/null. – ctac_ Jun 02 '21 at 19:48
  • 1
    `&>/dev/null` is shorthand for `>/dev/null 2>&1`. Given the clarification above, it isn't needed. That said, I believe the note about `$?` still holds true. – Charles Duffy Jun 02 '21 at 19:50
0

If I read it right...

grep -l "$word" "$filename" 2>&- || echo "not found"

If $word exists in $filename the -l option will output the name of the file.
If not, grep will return an error exit code and the || ("or") will execute the echo.

$: echo foo > bar
$: grep -l foo ??? 
bar
$: rm bar
$: grep -l foo ??? 2>&- || echo "not found"
not found

The 2>&- closes STDERR so that grep doesn't throw an error message of its own.
Without it -

$: grep -l foo ??? || echo "not found"
grep: ???: No such file or directory
not found

Of course https://mywiki.wooledge.org/BashPitfalls#myprogram_2.3E.26- advises against closing standard streams, so you should probably use 2>/dev/null.

So, the whole script:

#!/bin/bash
read -p "Filename: " filename
read -p "Word: "     word
grep -l "$word" "$filename" 2>/dev/null || echo "not found"
Paul Hodges
  • 13,382
  • 1
  • 17
  • 36