9 ms·
I know you’re not asking for awk protips but you can prefix the block with a match condition for processing. ... | grep foo | awk ‘{print $6}’ | ... becomes
by jcims 7y ago
I know you’re not asking for awk protips but you can prefix the block with a match condition for processing.
... | grep foo | awk ‘{print $6}’ | ...
becomes
... | awk ‘/foo/{print $6}’ | ...
If you start working this into your awk habits you’ll find delightful little edge cases that you can handle with other expressions before the block (you can, for example, match specific fields).
- bloopernova 7y agoI always forget about that, and I should try more to remember it. Thank you for the tip!
- mistahenry 7y agoOn the other hand, grep can be far faster for searching alone than awk. I almost always use an initial grep for the string that will most reduce the input to the rest of the pipeline. Later, it feels idiomatic to mix in awk with matches like you suggested
- davidgould 7y agoDepends on the awk. mawk is surprisingly fast.
- just_myles 7y agoRight. I don't consider that particular exhaustive at all and this has helped me when I wanted to do quick searches.
- 3xblah 7y agoNo one has mentioned changing the default field separator, e.g., awk FS=: '{print $1}' instead of cut -d: -f1 awk FS="<" '{print $2}' instead of cut -d'<' -f2 awk FS=">" '{print $1}' instead of cut -d'>' -f1
- chaps 7y agoNo need to explicitly set FS! Just use: echo test,123 | awk -F, '{print $1}'
- 3xblah 7y agoYikes. The syntax I had was wrong anyway. Should have been awk 'BEGIN {FS=":"};{print $1}' One benefit of the FS variable over -F, at least in original awk, is that by using FS the delimiter can be more than one character. I guess that's why I remember FS before I remember -F. More flexible.
- emmelaich 7y agoTo pile on :-) you often want -w (match word) flag to grep. In awk, I couldn't find how to do this. I tried /\bfoo\b/ and /\<foo\>/ but neither worked. I don't know why and don't care enough which brings me to my major awk irritation ... It doesn't use extended or perl REs, which makes it quite different to ruby, perl, python, java. Now, according to the man page it does; at least on OSX (man re_format) but as mentioned it didn't work for me. Details $ echo fish | awk '/\bfish\b/' gets nothing, vs $ echo fish | perl -ne '/\bfish\b/ && print' fish
- emmelaich 7y agoUGH! Found the problem; it simply doesn't work. Assuming the OSX awk is the same as the freebsd awk there is a very old open bug on this: awk(1) does not support word-boundary metacharacters https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=171725 https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=171725
- jolmg 7y ago\< and \> work with GNU's awk: $ printf "fishstick\nfish\ngoldfish\n" | awk '/\<fish\>/' fish
- asicsp 7y agoGNU awk supports \< and \> for start and end of word anchors, which works for GNU grep/sed as well GNU awk also supports \y which is same as \b as well as \B for opposite (same as GNU grep/sed) Intererstingly, there's a difference between the three types of word anchors: $ # \b matches both start and end of word boundaries $ # 1st and 3rd line have space as second character $ echo 'I have 12, he has 2!' | grep -o '\b..\b' I 12 , he 2 $ # \< and \> strictly match only start and end word boundaries respectively $ echo 'I have 12, he has 2!' | grep -o '\<..\>' 12 he $ # -w ensures there are no word characters around the matching text $ # same as: grep -oP '(?<!\w)..(?!\w)' $ echo 'I have 12, he has 2!' | grep -ow '..' 12 he 2!
- emmelaich 7y ago