0

How can I use grep, sed, awk, or other Linux tool or bash script to search each line of a file for the sequence “\t$month\t$day\n”, where…

\t = tab  
\n = new line  
$month = Sep   #$month is a variable with the content “Sep”  
$day = 4       #$day is a variable with the content “4”? 

Using grep, I can find \t, \n, $month, and $day individually, but to reduce false positives, I want the tool(s) to search each line of the file for the combination “\t$month\t$day\n”, and upon a match, send the line(s) to standard output, i.e., the console.

How can I search for the combination “\t$month\t$day\n” per line of the file, and have the tool output each matching line to the console?

Example: Here are the contents of the file “start-with-core”

$ cat start-with-core  
core4321        Sep     3  
core.1234       Nov     4  
core4   Sep     4  
core10  Sep     4  
core11  Nov     4  
core44  Sep     2  
core400 Sep     3  

There is one tab after the first field (column), one tab after the second, and a new line character after the third.

$ echo $month  
Sep  
                                                                             
$ echo $day    
4  

$ grep $'\n'  start-with-core  
core4321        Sep     3  
core.1234       Nov     4  
core4   Sep     4  
core10  Sep     4  
core11  Nov     4  
core44  Sep     2  
core400 Sep     3  

$ grep $'\t'  start-with-core  
core4321        Sep     3  
core.1234       Nov     4  
core4   Sep     4  
core10  Sep     4  
core11  Nov     4  
core44  Sep     2  
core400 Sep     3  

$ grep "$month"  start-with-core  
core4321        Sep     3  
core4   Sep     4  
core10  Sep     4  
core44  Sep     2  
core400 Sep     3  

$ grep "$day" start-with-core
core4321        Sep     3  
core.1234       Nov     4  
core4   Sep     4  
core10  Sep     4  
core11  Nov     4  
core44  Sep     2  
core400 Sep     3  

Any ideas? Thanks! Estudiante

///\\

1
  • Do your lines really have trailing blank chars at the end of them? If not then please edit your question to fix that.
    – Ed Morton
    Sep 6, 2021 at 21:13

1 Answer 1

2

grep looks for lines matching a pattern, so it seems you want to find lines that end in \t$month\t$day.

So:

TAB=$(printf '\t') # or TAB=$'\t' with many shells
grep "$TAB$month$TAB$day\$" < your-file

Where $ (here escaped as it's otherwise use by the shell for parameter expansion, even if in most shells it's safe to leave it unescaped when followed by "), matches at the end of the subject.

awk is good for working with tabular data. You could use it to match on lines where the last field is $day and the second-last is $month with:

M=$month D=$day awk -F '\t' '
  $NF == ENVIRON["M"] && $(NF-1) == ENVIRON["D"]
  ' < your-file

awk's == does a numeric comparison if both operands look like numbers and are not otherwise explicitly typed as strings like here, so it would match on Sep 4 but also on Sep 04/4.0/4e0...

1
  • +1. Obviously given no escapes in the shell vars, as in the posted example, you could alternatively just do awk -v m="$month" -v d="$day" -F '\t' '$NF == m && $(NF-1) == d' < your-file.
    – Ed Morton
    Sep 6, 2021 at 21:18

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.