I often grep CSV files with column names on the first line. Therefore, I want the output of grep to always include the first line (to get the column names) as well as any lines matching the grep pattern. What is the best way to do this?
sed ( sed 1q or sed -n 1p ) and head ( head -n 1 ) are the more appropriate tools for printing the first line from a file. For printing the last line of a file, you have tail -n 1 or sed -n '$p' .
The grep command has an -m or --max-count parameter, which can solve this problem, but it might not work like you'd expect. This parameter will make grep stop matching after finding N matching lines, which works great as it will limit the output to one line, always containing the first match.
The -n ( or --line-number ) option tells grep to show the line number of the lines containing a string that matches a pattern. When this option is used, grep prints the matches to standard output prefixed with the line number. The output below shows us that the matches are found on lines 10423 and 10424.
sed '1p;/pattern/!d' input.txt
awk 'NR==1 || /pattern/' input.txt
grep1() { awk -v pattern="${1:?pattern is empty}" 'NR==1 || $0~pattern' "${2:-/dev/stdin}"; }
grep doesn't really have a concept of line number, but awk does, so here's an example to output lines contain "Incoming" - and the first line, whatever it is:
awk 'NR == 1 || /Incoming/' foo.csv
You could make a script (a bit excessive, but). I made a file, grep+1, and put this in it:
#!/bin/sh pattern="$1" ; shift exec awk 'NR == 1 || /'"$pattern"'/' "$@"
Now one can:
./grep+1 Incoming
edit: removed the "{print;}", which is awk's default action.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With