12 ms·
Learn to use Awk with hundreds of examples
- bananicorn 9y agoI'm wondering: Does awk really provide that more value over sed while being easier or faster to use than a fully-fledged scripting language (thinking of perl, python, etc).? (and yes, one may argue that awk IS a scripting language, I'm not disputing that, just asking)
- __MatrixMan__ 9y agoI'll admit that I don't know perl, which I believe is the typical sed+awk replacement. According to my potentially miscalibrated gut, referencing a "fully-fledged" scripting language in a shell script or at the command line is an indication that you should probably just be working in that environment in the first place. There will be exceptions, it depends chiefly on the problem being solved, but overall I prefer my shell scripts to reference utilities with very specific purposes. It feels UNIXier that way.
- sohkamyung 9y agosed and awk complement each other, I think. 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.
- padthai 9y agoI use awk every day because I need state (I work with text files full of sections and subsections) but I am sure that there has to be something better out there. What is the definitive tool to process text? Perl? Haskell? Some Lisp dialect?
- rlonstein 9y ago> 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]. [1] http://www.nongnu.org/txr/ http://www.nongnu.org/txr/ [2] https://stedolan.github.io/jq/ https://stedolan.github.io/jq/
- kazinator 9y agoHi; I replied to your Github gist quite a while ago: https://gist.github.com/rlonstein/90d53fdeea31d2137737 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.
- macintux 9y agoBiased because I've used Perl for over 20 years, but yeah, that's clearly one of its core reasons to exist. Regular expressions built into the language syntax instead of as a library makes a big difference.
- znpy 9y agoPerl. It was designed for doing just that :)
- Annatar 9y agoPerl has an intangible "write once" property: since it allows for writing extremely sloppy code under the "there is more than one way to do it!" mantra, nobody, including the original author can debug it afterwards. Not even with the built in Perl debugger. Perl encourages horrible spaghetti code. 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.
- Xophmeister 9y agoIndeed: sed is useful for making small, line-wise tweaks to text. To be honest, I use it rarely (and this is largely because its regexp flavour leaves a lot to be desired). Things like delete the header line[1S] or a simple replacement[2S]. It, like Awk, has some useful line targeting functions (e.g., print lines between two regular expressions[3S], etc.) Awk, on the other hand, is more like a finite state machine for text processing, with the notion of records and fields baked in[4]. You can do the same thing in Awk as in sed (see [*A] references), but it's often easier in sed; vice versa, some things would be impossible or very difficult to do in sed which would be easy in Awk (e.g., [4], which prints the fifth field whenever the first field is "foo"). This doesn't even get into the multiline/statewise stuff you can do in Awk, but the examples would be too big/specific to fit into this comment. 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.html https://www.gnu.org/software/gawk/manual/gawkinet/gawkinet.h...
- fosco 9y agoI did not know gawk had networking support I wonder if it could be used on network traffic on the fly. Sort of like irules on an f5. Thank you for sharing!
- vram22 9y ago[3A] awk '/start_regex/,/end_regex/ {print}' 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)
- lo_stronzo 9y ago"sed is useful for making small, line-wise tweaks to text." 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.
- bananicorn 9y agoHonestly, that makes sense - doing multiline replaces with sed isn't very convenient (I believe it's possible if you replace newlines with NULL). I guess I'll probably learn awk then, it can't be that hard with the examples from this repo^^
- cyborgx7 9y agoTo me, awk always occupied an awkward (no pun intended) spot. Too complicated for a proper single purpose command-line program. Not expressive enough to be in the same sphere as a scripting language like the ones you mentioned. I was hoping this article might illuminate its purpose, but I'm still just as clueless.
- asicsp 9y agocould you give an example use-case? >Too complicated please try out examples given and let me know if it helps you to understand the syntax better
- oblio 9y agoawk is my go-to tool for simple command line tokenizer. Hard to beat: awk '{ print $1; }' Other than that... not really. Maybe the advantage would be ubiquity, if you really, really want to avoid Perl.
- cyborgx7 9y ago>Hard to beat: awk '{ print $1; }' How about: cut -f 1 -d ' ' You don't even need the -d flag if the you happen to be able to use the default delimiter, like in your example.
- zb 9y agoI used to regularly do ad-hoc text processing, typically on a 24 hour log of GPS data (on an early-2000s-era computer). Surprisingly enough, awk is many times faster than cut for any data set big enough for you to notice time passing.
- deleted 9y ago[deleted]
- fnord123 9y agoAwk delimits on whitespace by default. cut cannot do that afaict. So if you have something like this cut wont work: apples 1 bananas 2
- ninkendo 9y agoExactly, which makes cut kinda shit for 99% of common "split-on-whitespace" tasks IMO.
- dredmorbius 9y agoYou can always use awk with IFS/OFS values to clean up the delimiters so you can pass the data off to cut ;-)
- sbmassey 9y agoThere's always plain old bash while read a _; do echo $a; done
- mohaine 9y agoIf I remember correctly, I believe perl was created to combine the power of sed and awk into a single tool so you didn't have keep switching back and fourth between the two. Personally, I would suggest AWK for one to two liners when doing some one time data transform tasks. Anything more complicated and I would suggest a more "fully-fledged scripting language"
- brians 9y agoFor me, yes. I use Python plenty too, but Awk is great for a tiny state machine, and unique in the ease of setting up an event stream view of a text file. I could use Python, add a loop and a big set of conditionals—but a one page awk program gets all that right.
- asicsp 9y ago* for search and replace on entire lines and other address based filtering, I prefer sed (or perl if I need PCRE features like non-greedy, lookarounds, code in substitution section, etc) * for field processing, most multiple line processing, use of logic operators, arithmetic, control structures etc, I prefer awk or perl * this repo is aimed at command line text processing tools, most awk examples given are single line, a few are 2-3 lines. Personally I prefer Python for larger programs ---- See also: https://unix.stackexchange.com/questions/303044/when-to-use-grep-less-awk-sed https://unix.stackexchange.com/questions/303044/when-to-use-...
- abecedarius 9y agoIf you already know it, then yes, it's still handy sometimes. And it's a small language, unlike Perl. OTOH I'm not sure I'd recommend bothering to learn it. Python is more verbose in Awk's domain, but not by so much as makes a huge difference, except at the scale of one-liners. (Or a-few-liners, at least.) Another reason to learn it: the AWK book (by Aho, Kernighan, and Weinberger) is a great very short intro to the spirit of Unix-style coding. You could think of learning Awk as just the price of admission to that intro, paid along the way. I wrote plenty of Awk in the 90s -- https://github.com/darius/awklisp https://github.com/darius/awklisp isn't very representative but it was fun.
- cup-of-tea 9y agoIt's more powerful than sed while being much easier and quicker to use than perl or python, so yes. I use it quite often just as a filter. sed is still good for some things.
- Annatar 9y agoAWK is a programming language. In the AWK book by Aho, Weinberger and Kernighan, towards the end of the book they implement an arbitrary assembler, the virtual processor and a virtual machine for the machine code they just invented to run. They also implement a relational database management system in AWK, as well as an autoscale graphing solution. I myself have implemented XML SOAP command line client, a backup solution, a SAN UUID management application and an automated Oracle RAC SAN storage migration solution, a configuration management, and an Oracle database creation / management applications in AWK. Usually I develop a thin getopts shell wrapper around an AWK core. Works every time, the executables are on the order of a few KB (the largest so far, the XML SOAP client is 24.5 KB) and they all run like a bandit. Memory requirements are miniscule. Dependencies are minimal: the only external dependency so far in my software has been the xsltproc binary from the libxslt package. AWK is easier to use than Python or Perl, and is much faster than either of those. Typical code density ratio of Python versus AWK is 10:1, sometimes more. This means that if you have a 650 line Python program, you can implement the same functionality in about 280 lines of AWK, and the program will be far simpler. I've once collapsed a 280+ line Python program into a simple 15 lines of code in AWK. AWK is an extremely versatile, powerful programming language. For even more speed, AWKA can be used to transpile AWK source into C and then it will call an optimizing C compiler to compile it into a binary executable. Typical speedup is on the order of 100%, so if your AWK program ran in 12 seconds, it'll now finish in six.
- segmondy 9y agoI once introduced AWK to a team and shared the same book with them. They didn't know that AWK was a programming language. Told them they could achieve more faster with AWK than using python & php for transforming and shuffling around data. They looked at me like I was crazy. :(
- zephyrfalcon 9y ago"""Typical code density ratio of Python versus AWK is 10:1, sometimes more. This means that if you have a 650 line Python program, you can implement the same functionality in about 280 lines of AWK, and the program will be far simpler. I've once collapsed a 280+ line Python program into a simple 15 lines of code in AWK.""" How does this work? I am not saying it can't be done, but the main benefit of Awk seems to be quick one-liners, which are possible because you get "records" (splitting on whitespace) and lines (splitting on newline) and looping for free. But for larger programs, this easily translates to Python; just call readlines(), loop over it, call split() on each line. I would think that at this point, Awk doesn't have much of an advantage anymore... but apparently your experiences are different. What are some Awk constructs that would take a lot more code in Python?
- tmaly 9y agoI still use a little sed once in a while, but Perl has replaced most of the tools like awk for me.
- jstimpfle 9y agoThe advantage of awk is that it is faster in some cases and a little more convenient for simple command-lines due to automatic field splitting. The disadvantage is that it swallows errors silently even more than perl (I think).
- Annatar 9y agoI'd say that AWK's single weakness is a lack of built-in debugger or even `set -x` tracing mode like the shell has.
- tmaly 9y agoyes I agree, I have seen awk perform faster in some cases, but for the general case, I prefer something a little more flexible like Perl
- augustk 9y agoAwk is also a part of POSIX.
- mathiasrw 9y agoIf you have access to npm in your environment then try rexreplace next time.
- waynecochran 9y agoYep Perl* is a great swiss army knife that rendered sed and awk obsolete -- I am old enough (50) to have been thru this progression. It's funny to see awk and sed come back around. (It's a little like functional programming being rediscovered when Lisp has been around since the dawn of time). * I think Perl got carried away when it added objects and folks started writing large programs with it (although I have written some large scripts for biologists doing genetic studies -- which is interesting popular use case == there are google groups and O'Reilly books focused on this use case). Also, Larry Wall really humped the shark with Perl 6.
- aseure 9y agoI would also recommend the good awk blog post series of Jonathan Palardy: * http://blog.jpalardy.com/posts/why-learn-awk/ * http://blog.jpalardy.com/posts/awk-tutorial-part-1/ * http://blog.jpalardy.com/posts/awk-tutorial-part-2/ * http://blog.jpalardy.com/posts/awk-tutorial-part-3/
- cannedslime 9y agoThanks to you... and OP! I have been using posix systems for years but never really touched awk because what I have seen have seemed like archaic chants of dark magic, very good resources for learning about this nifty tool.
- asicsp 9y agoglanced a bit, looks good.. will add it to further reading section, thanks :) has some minor issues though > modern (i.e. Perl) regular expressions nope, supports only ERE.. doesn't have non-greedy, lookarounds, etc > $ cat netflix.tsv | awk '{printf "%s %15s %.1f\n", $1, $6, $5}' | sed 1d could have just added NR>1 condition..
- matt_wulfeck 9y agoYeah that’s really tough for me. PCRE really sets the bar for modern regular expression engines. Awk predates it by a decade.
- microtherion 9y agoTWO decades!
- kazinator 9y agoNot to mention that awk takes filename arguments, so this is an egregiously useless use of cat.
- twmb 9y agoFrom the second post, > Alternatively, awk '{print $2}' netflix.tsv would have given us the same result. For this tutorial, I use cat to visually separate the input data from the AWK program itself. This also emphasizes that AWK can treat any input and not just existing files.
- michaelsbradley 9y agoSee also the GNU Awk manual (currently Edition 4.2, Oct 2017) GAWK: Effective AWK Programming https://www.gnu.org/software/gawk/manual/gawk.pdf https://www.gnu.org/software/gawk/manual/gawk.pdf
- asicsp 9y agoyup, nothing beats it for being complete reference as well as tutorial I added references to it throughout the chapter
- 0xFFFE 9y agoI use sed & awk all the time. It is an invaluable tool while debugging issues, extracting fields from log files etc. I am not dissing python or perl, I use python extensively as well. But while you are in the middle of an incident, hard to beat a quick oneliner, like this random example. awk -F":" 'BEGIN{total=0}{if($3>240)total+=$3}END{print total}' /etc/passwd
- indescions_2017 9y ago>>> I use sed & awk all the time. Me too. For example, number of unique IP requests in a log file in milliseconds ;) $ awk '{ print $1 } ' caddy_log | sort | uniq | wc -l But rarely compose my own from scratch. It's mostly copy paste. And store in admin bin for future use.
- dietr1ch 9y agoThere's `sort -u` which should be able to avoid some work.
- ninkendo 9y agoDumb side note: I always end up using `awk '{print $1}'` instead of `cut -f1` because cut's field separation defaults are unwieldy in that it doesn't intelligently consider any whitespace to be a field separator, which is what I need 99% of the time.
- ptman 9y agosometimes (if there are not mixed spaces and tabs) tr -s ' ' < input | cut -f1 helps
- asicsp 9y agoNo need so many commands :) $ cat duplicates.txt abc 7 4 food toy **** abc 7 4 test toy 123 good toy **** $ awk '!seen[$2]++' duplicates.txt abc 7 4 food toy **** $ awk '!seen[$2]++{cnt++} END{print +cnt}' duplicates.txt 2
- nsebban 9y agoCommands like cat, cut, sort, uniq and awk are still pretty relevant nowadays. Even on huge volumes of data.
- assafmo 9y agoEspecially on huge volumes of data.
- dugmartin 9y agoawk is what got me into web programming around 1994. I was working at a GE subsidiary and all the documentation for the RTOS I was working on was printed in huge binders from actively maintained Interleaf documents. Once I found the SGML source documents on the server it only took a few hours to learn enough awk to convert the SGML into a fully interlinked set of HTML documents with a table of contents. Granted SGML to HTML is not that hard but it was fun and useful and much nicer to search as opposed to laying out a bunch of binders on my cube's desk.
- johnnylambada 9y agoWhile we're on the subject, let's not forget to avoid parsing HTML with regex: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 https://stackoverflow.com/questions/1732348/regex-match-open...
- ams6110 9y agoGenerally good advice, but can be OK in specific situations where you have a known HTML structure and are just scraping some values out of it. This is not so much parsing HTML as it is matching the patterns of the values you want to extract.
- johnnylambada 9y agothe pon̷y he comes he c̶̮omes
- jdnier 9y agoA regex can be used effectively to tokenize XML-like markup, including a lot of HTML—sometimes called shallow parsing. https://stackoverflow.com/a/6638578/234823 https://stackoverflow.com/a/6638578/234823 Attribute value minimization would be one limitation, since that regex is for XML, but it's a more robust approach than writing naive "<x>.*</x>"-style regexes.
- AceJohnny2 9y ago> A regex can be used effectively to tokenize XML-like markup ...isn't that how all tokenizers for all (confusingly-named) context-free languages work?
- rebolyte 9y agoDefinitely check out the rest of that repo as well; it's a gold mine!
- asicsp 9y agothanks :)
- SEJeff 9y agoawk1line.txt is the original and still one of the absolute de-facto best awk references with examples: http://www.pement.org/awk/awk1line.txt http://www.pement.org/awk/awk1line.txt
- Annatar 9y agoThe best reference is "The AWK programming language" by Aho, Weinberger and Kernighan.
- geospeck 9y agoWhich is available at the archive.org: https://archive.org/details/pdfy-MgN0H1joIoDVoIC7 https://archive.org/details/pdfy-MgN0H1joIoDVoIC7
- asicsp 9y agoyup, that is good resource they are explained here: http://www.catonmat.net/series/awk-one-liners-explained http://www.catonmat.net/series/awk-one-liners-explained which I mention it in further reading section
- mynegation 9y ago20 years ago when Python was not pre-installed on most systems, the awk/gawk used to be my Swiss army knife. My first real programming job was translating 1000 LOC awk program into C. The syntax was simpler than ed, and getting combination of grep, uniq, cut etc correct. I call it "Excel of the command line"
- dmd 9y agoIt's still extremely useful for those of us in industries where change comes veeerrrryyyy slooowwwly. For instance, most production servers I work with are still on Python 1.5.2 if they have Python at all - but awk, that I can depend on!
- ams6110 9y agoExcept is it gawk? The gnu enhanced awk is not universally installed, so for best portability stick with standard awk.
- dmd 9y agoAlmost certainly not!
- majewsky 9y agoAnd on the other end of the spectrum, it's becoming relevant again in container ops. A random container is not likely to have a Python, Ruby or even Perl, but if it has a shell, it most certainly also has an awk. Even Alpine has one in their busybox.
- kazinator 9y agoTXR Lisp Awk macro: http://www.nongnu.org/txr/txr-manpage.html#N-000264BC http://www.nongnu.org/txr/txr-manpage.html#N-000264BC Has analogs for all salient POSIX Awk features and most GNU Awk extensions. (Of course, not semantic cruft like the weak type system, or uninitialized variables serving as zero in arithmetic.) Plus: * You can embed (awk ...) expressions anywhere, including other (awk ...) expressions. * You can capture a delimited continuation (awk ...) and yield out of there. * It supports richer range expressions than Awk. Range expressions combine with other range expressions unlike in Awk, so that you can express a range which spans from one range to another. Also, there are variations of the operator to exclude either endpoint of the range: rng, -rng, rng- and -rng-. * You can "awk" over a list of strings, possibly an infinitely lazy one. 1> (awk (:inputs '("a" "b") '("c" "d")) (t (prn nr fnr rec))) 1 1 a 2 2 b 3 1 c 4 2 d nil * It has a return value: whatever the last :end returns, or else nil: 1> (awk (:end 42) (:end 43)) [Ctrl-D] 43 Build a list from the first fields of /etc/passwd: 1> (build (awk (:inputs "/etc/passwd") (:set fs ":") (t (add [f 0])))) ("root" "daemon" "bin" "sys" "sync" "games" "man" "lp" "mail" "news" "uucp" "proxy" "www-data" "backup" "list" "irc" "gnats" "nobody" "libuuid" "syslog" "messagebus" "avahi-autoipd" "avahi" "usbmux" "gdm" "speech-dispatcher" "kernoops" "pulse" "rtkit" "hplip" "saned" "kaz" "vboxadd" "sshd" "oprofile" "ntp" "lightdm" "colord~" "whoopsie" "postfix") Type conversion of fields (which are just strings) is achieved by an elegant operator fconv which takes a condensed notation such as (fconv i : r : xz) which means convert the first field to integer as a decimal integer, the last field as a hexadecimal integer and the fields in between as reals. The xz means that if the last field is invalid, it gets converted to zero rather than nil. These letters are just the names of lexical functions available in the awk scope, rather than built-in fconv behaviors.
- feelin_googley 9y agoKernighan and Van Wyk, "Timing Trials, or, the Trials of Timing: Experiments with Scripting and User-Interface Languages" (1998) http://web.archive.org/web/20000829071436/http://inferno.bell-labs.com:80/cm/cs/who/bwk/interps/pap.html http://web.archive.org/web/20000829071436/http://inferno.bel... AWK, Perl, Tcl, Scheme, C, Java, Limbo, Visual Basic What if k scripting language was included in those experiments? http://kparc.com/z/bell.k http://kparc.com/z/bell.k k3: 1. "Basic Loop Test" \t 1000000(1+)/0 2. "Ackermann's Function Test" \t {:[~x;y+1;~y;_f[x-1;1];_f[x-1;_f[x;y-1]]]}[3;7] 3. "Indexed Array Test" \t x(x;|x:!200000) 4. "String Test" \t f:{(x>#:){(i _ x),(1+i:_.5*#x)#x:,/("123";x;"456";x;"789")}/y};do[10;f[500000;"abcdef"]] 5. "Associative Array Test" \t {+/("0123456789abcdef"16_vs'!x)_lin$!x}40000 6. "File Copy Test" `f 0:(30000 _draw 300)#\:"king " \t `f 0:0:`f 7. "Word Count Test" \t (#:;+/(+/1<':" "=)';+/#:')@\:0:`f 8. "File Reversal Test" \t `f 0:|0:`f 9. "Sum Test" `f 0:100000#,"-123.456" \t +/0.0$0:`f Source: http://web.archive.org/web/20010501041644/http://www.kx.com:80/a/k/examples/bell.k http://web.archive.org/web/20010501041644/http://www.kx.com:...
- kbenson 9y agoFrom what I know (which is not well sourced), the big problem with K is that it didn't have an open and accessible interpreter for a long time, and that hampered adoption. I know 5-6 years ago I was interested in it, but couldn't find any interpreters that were free for non-commercial and commercial user (it was mostly work related interest), and didn't stumble across Kona[1] at the time. Not it's on my list of languages to look into again, but that's a long list. 1: https://github.com/kevinlawler/kona https://github.com/kevinlawler/kona
- geospeck 9y agoThere is also available the source code[1] of the original awk, "The One True Awk" as Brian Kernighan refers to it at his Princeton webpage. [1]http://www.cs.princeton.edu/~bwk/btl.mirror/ http://www.cs.princeton.edu/~bwk/btl.mirror/
- superasn 9y agoThese are the best stories on HN and why i subscribed here in the first place. I have often seen awk used so many times on SO but I've always put it up for something later to learn. Finally today I have some basic understanding of awk and this is really great stuff! I did get by with Perl but this is definitely more handy and the example approach to teaching it makes is super easy to understand!
- asicsp 9y agothanks :)