-1

I am using "grep" in a while loop (to read line by line) a long document (this long file contain multiple paragraphs,each paragraph starts with a date/time).

The purpose is to find certain phrase and print or echo the paragraph's date/time beside that phrase. How can I "echo" or "print" the letters "NULL" when grep can't capture the phrase. For example:

Let's say we have these three paragraph in the file (test.txt):

 20170101,05:00 AM, I am using grep to read certain phrase1 in a long document. 
 20170102,09:30 AM, I am using grep to read certain phrase2 in a long document. 
 20170103,05:30 AM, I am using grep to read page in a long document. 

How can I echo or print a "certain phrase" and date time and if "certain phrase not available replace the output by NULL so the output as follow:

 20170101,05:00 AM,certain phrase1
 20170102,09:30 AM,certain phrase2
 20170103,05:30 AM,NULL
.
.
.

I use the following:

while read -r line; do
date=$(grep -c "201*")
phrase=$(grep  -Eo "certain phrase")

echo $date,$phrase
done < test.txt
2
while read -r line; do
  date=$(grep -Eo  "201.{12}.M," <<< "$line")
  phrase=$(grep  -Eo "certain phrase" <<< "$line")
  echo "${date}${phrase:-NULL}"
done < test.txt

You were reading the line, but not grepping against it. I tweaked the regex on the first grep to match the date part (instead of -c counting it). The last piece to the puzzle was to echo the $phrase variable with parameter expansion to replace an empty value with the word "NULL".

  • Woww!! This is great solution. Thank you Jeff so much. Actually, I forgot the flag -ne after echo to print the output on the same line. I have one problem. Why the output of echo -ne "${date}${phrase:-NULL}" is in the opposit direection? I mean it output phrase first or null then date/time although the command is to output dsate time first? – user88036 May 12 '17 at 16:40
  • It outputs the date first for me, on your sample data. I didn't use -ne, but even with those options, it prints the date & phrase for each match, in sequence. – Jeff Schaller May 12 '17 at 16:54
2

I'd suggest something like

awk 'BEGIN {OFS=FS=","} 
  /201/ {
    if (match($0,"certain phrase")) {
      print $1, $2, substr($0,RSTART,RLENGTH+1)
    } else {
      print $1, $2, "NULL"
    }
  }' file

Testing with your input data:

$ awk 'BEGIN {OFS=FS=","} 
>   /201/ {
>     if (match($0,"certain phrase")) {
>       print $1, $2, substr($0,RSTART,RLENGTH+1)
>     } else {
>       print $1, $2, "NULL"
>     }
>   }' file
 20170101,05:00 AM,certain phrase1
 20170102,09:30 AM,certain phrase2
 20170103,05:30 AM,NULL
2

Instead of grepping in while, do all in a single sed script:

sed 's/\( *[0-9]*,[^,]*,\).*\(certain phrase[^ ]*\).*/\1\2/;t
  s/\( *[0-9]*,[^,]*,\).*/\1NULL/' file.txt

sed already handles the line-by-line for you, and in each line the script executes a replacement with the s command:

The first part [0-9]*,[^,]*, is supposed to match the date string. By surrounding it with \(\), we can reuse it in the replacement as \1

The same for the second \(\), containing the phrase and trailing non-blanks (adapt if necessary), which is referred to as \2. Everything else is thrown away.

If this replacement was done, the t command jumps to the end of the script, as we are done. If no replacement could be done, everything after the date is replaced by NONE

  • Thank you, very much. I highly appreciate if you explain the command a bit. – user88036 May 12 '17 at 16:41
  • That's a pretty straightforward script. If the first substitution matched and substituted something, you're done (t). Otherwise, proceed with the second substitution. – tripleee May 12 '17 at 16:56
  • 1
    Added a little more verbose explanation, if you are not that familiar with sed – Philippos May 12 '17 at 17:07
0
perl -lne 'print /^((?:.+?,){2})/, /\h\K(certain\h+phrase\d+)/ ? $1 : "NULL"' < test.txt

Here we get the first two comma-delimited fields and then look for "certain phrase". If it is found, use it else "NULL" is used.

Your Answer

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