set -vn
   set -o pipefail
   set -e
   if grep -v '^#' file.tx | grep -P 'name' file.tx; then \
      echo "    No name"; exit 0;\
      echo " This message is print from file.tx" \
      cat file.tx; fi

1) This code above is try to grep if name is not exist in file.tx then, it will echo " No Name ". I want only to grep the word if it not exits in uncommented line but it seems doesn't work.

2) How I want to make if first statement is false, it will go to second statement. The command above seem doesnt't work.

Note: This code is write in Makefile and the target name is try2

  • 1
    Please don't post images of text. – Haxiel Nov 29 '18 at 6:40
  • I'm uncertain what you mean by that second question. Could you explain? Also change the image to plain text please. It's difficult to read. – Kusalananda Nov 29 '18 at 7:03
  • For the second question is, if the string is exits, it will go to second statement wich it "cat file". the above command seem doesn't work – daffodil Nov 29 '18 at 7:15
  • The first three lines are run in separate shell processes and thus useless. BTW: set -e is useless anyway since make calls the commands via sh -ce cmdline unless you use make -i. – schily Nov 29 '18 at 10:23

The issue is that instead of grepping for name in the non-commented data in file.tx, you run grep against the original file

grep -v '^#' file.tx | grep -P 'name' file.tx
                                     will not read from pipe

Instead, use

grep -v '^#' file.tx | grep -q 'name'

i.e., don't make the second grep in the pipeline read from the original file. Also, since you are only interested in the exit status of grep (for use in the if statement), use it with -q.

Taking your second question into account, it seem, if I understand correctly, that you want to run cat file.tx only if the string name is present outside of comments. In this case you have your logic backwards.

if grep -v '^#' file.ex | grep -q 'name'; then

This will be true if the string name occurs in a non-commented line. If you want to cat the file, then you would need to do it here:

if grep -v '^#' file.ex | grep -q 'name'; then \
    cat file.tx; \
else \
    echo 'No name'; \

I'm uncertain about the exit 0 as that has implications for the rest of the Makefile target. If you want the target to fail if name is not present, then do exit 1 after the echo, otherwise don't exit at all (unless you have further shell code that you don't want to execute in the same Makefile target).

I'm also noticing your cd ../... Unless you have a file.tx in the current directory and in the directory ../.., the cat would fail for you. You have not mentioned why you step two directory levels up, so I can't say more about this.

Also note that the cd will be "undone" as soon as the shell snippet is completed as make runs each individual line of a target in a separate shell instance. This also means that the various set instructions that you have are run in separate shells.

  • for second grep, i want non-match string. If, there is no match string "name", then it will print " No Name" – daffodil Nov 29 '18 at 7:26
  • @daffodil See updated answer – Kusalananda Nov 29 '18 at 7:38

If I understand the question, you have a file like this:

# a comment with the magic word name

some stuff that does not include the magic word

and you want "No name" to be printed. If the first line were uncommented, then "No name" should not be printed.

The following should do that:

if grep -v '^#' file.tx | grep -q name; then
       echo "no name"

In your code, the second grep includes the filename, so it is not looking at the piped input from the first one. Also, since you're not using a Perl regexp, I dropped the -P, and I also added -q to suppress any output that grep might print if something matched.

  • for second grep, I don't non-match string. I'd tried grep -Fv but it seem doesn't work. – daffodil Nov 29 '18 at 7:17
  • I also had tried grep -I , but it still doesn't work – daffodil Nov 29 '18 at 7:18
  • correction : I want non-match string. I also had tried grep -I , but it still doesn't work – daffodil Nov 29 '18 at 7:24

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.