sed works on a line by line basis.
awk can work on a whole file. Subsequent line operations can depend on the state of previous lines.
Each has its own operating domain and you have to decide which tool is the best one for the task you have in mind.
sed works on a line by line basis.
awk can work on a whole file. Subsequent line operations can depend on the state of previous lines.
Each has its own operating domain and you have to decide which tool is the best one for the task you have in mind.
I also learned recently that GNU Awk has networking support[5]. I have no idea why!
[1S] sed '1d'
[1A] awk 'NR!=1 {print}'
[2S] sed 's/foo/bar/'
[2A] awk '{sub(/foo/, "bar")}'
[3S] sed -n '/start_regex/,/end_regex/p'
[3A] awk '/start_regex/,/end_regex/ {print}'
[4] awk '$1=="foo" {print $5}'
[5] https://www.gnu.org/software/gawk/manual/gawkinet/gawkinet.h...
can be simplified to:
awk '/start_regex/,/end_regex/'
because in awk, if no action is given, the default action is to print the lines (that match the pattern). And if the pattern is omitted but the action is given, it means do the action on all lines of the input.
Edited to change:
print the line (that matches the pattern)
to
print the lines (that match the pattern)
Couldn't agree more!
A great example of this was using (surprised it wasn't mentioned) sed with the -i & 's///g' operators while "cleaning" hundreds (seriously) of HTML/PHP files from injected content at a shared hosting provider.
Similarly
sed 15q
will print only the 1st 15 lines of the input and then terminate. E.g.:
sed 15q file
or
some_command | sed 15q
So, when put in a shell script and then called (with filename arg or using stdin):
sed $1q
is like a specific use of the head command [1]; it prints the first n ($1) lines of the standard input or of the filename argument given - where the value of $1 comes from the first command-line argument passed to the script.
[1] In fact on earlier Unix versions I worked on (which did not have the head command (IIRC), I used to use this sed command in a script called head - similar to tail.
And I also had a script called body :) to complement head and tail, with the appropriate invocation of sed. It takes two command-line arguments ($1 and $2) and prints (only) the lines in that line number range, from the input.
What is the definitive tool to process text? Perl? Haskell? Some Lisp dialect?
Definitive? Being snarky, the one you have already installed and are familiar with. Like most I use Awk for one-liners, Perl if I need a little more or better regexes in a one- or two-liner. For the last several years I've been using TXR[1] if it gets complex. Lately I've been doing more fiddling with JSON than text and I'm using Ruby/pry and jq[2].
https://gist.github.com/rlonstein/90d53fdeea31d2137737
about a matter related to the hash bang line in the script.
TXR has a nice little hack (that apparently I invented) to implement the intent of "#!/usr/bin/env txr args ..." on systems where the hash bang mechanism supports only one argument after the interpreter name.
In the interest of fair and accurate disclosure, I earned my bread for 3.5 years debugging Perl code for a living and I've also had formal education in Perl programming at the university. I would never want to do that again.