awk: not an option: -i
checkPageExists() { local page=$1 curl -sI "$page" | awk '/^HTTP\/1.1/ { if ($2=="200") exit 0 else exit 1 }' } main() { for page in $pageList; do checkPageExists "$page" || continue done }
An example is worth one thousand words., so enjoy your reading !
[docker-ce-stable] name=Docker CE Stable - $basearch baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/stable enabled=1 gpgcheck=1 gpgkey=https://download.docker.com/linux/centos/gpg [docker-ce-stable-source] name=Docker CE Stable - Sources baseurl=https://download.docker.com/linux/centos/$releasever/source/stable enabled=0 gpgcheck=1 gpgkey=https://download.docker.com/linux/centos/gpgI want to list the IDs of those having
enabled=1
:
curl -s https://download.docker.com/linux/centos/docker-ce.repo | awk ' \ BEGIN { repoId=""; } \ /^ *$/ { repoId=""; } \ /^\[.*\]/ { repoId=$0; } \ /^enabled=1/ { if (repoId != "") { result=gensub(/[\[\]]/, "", "g", repoId); print result; } }'
docker-ce-stable
while read line; do echo -e "\t$line" echo "$line" | awk '{ link=$1; target=""; for(i=2; i<=NF; i++) { if($i!="->") link=link" "$i; else break; } for(j=i+1; j<NF; j++) target=target""$j" "; target=target""$NF; print " LINK: \047"link"\047, TARGET: \047"target"\047"; }' echo done < <(find -type l -exec ls -l {} + | awk '{ for (i=1; i<9; i++) $i=""; print $0; }')Explanations :
print
display single quotes '
(see comments of this answer){ print $0 }
or even { print }
works, but is redundant.h e l l o
cdefghi
z y x
line 1 line 2 line 3
1 2 3
SPACE
(default) or the specified OFS1 line 2 line 3 line 1line 2line 3line
\n
to the output (printf doesn't) :
\n
printf(string, expression list)
syntax :
echo 'abc' | awk '{ switch ($0) { case /[[:lower:]]+/: print "lowercase" break case /[[:upper:]]+/: print "uppercase" break } }'As a one-liner that can be pasted into the shell :
echo 'abc' | awk '{ switch ($0) { case /[[:lower:]]+/: print "lowercase"; break; case /[[:upper:]]+/: print "uppercase"; break; } }'
#!/usr/bin/env bash value1=120 # initial value : 160 # tested values : 200, 140, 100 # decreasing from the initial value : more bass sounds value2=0.5678 # initial value : 0.87055 # tested values : 0.747, 0.777, 0.789 # increasing values above 3.xxx : extreme bass sounds (?), hardly audible # around 0.5xxxxx : nice chime sounds value3=13 # initial value : 10 # tested values : 13, 17, 26 # increasing values : more high-pitched sounds # 26 makes some 'D2-R2' blips value4=128 # no effect so far :-( # initial value : 128 awk "function wl() { rate=64000; return (rate/$value1)*($value2^(int(rand()*$value3)))}; BEGIN { srand(); wla=wl(); while(1) { wlb=wla; wla=wl(); if (wla==wlb) {wla*=2;}; d=(rand()*10+5)*rate/4; a=b=0; c=$value4; ca=40/wla; cb=20/wlb; de=rate/10; di=0; for (i=0;i<d;i++) { a++; b++; di++; c+=ca+cb; if (a>wla) {a=0; ca*=-1}; if (b>wlb) {b=0; cb*=-1}; if (di>de) {di=0; ca*=0.9; cb*=0.9}; printf(\"%c\",c)}; c=int(c); while(c!=$value4) { c<$value4?c++:c--; printf(\"%c\",c)};};}" | aplay -r 64000
BEGIN
rule is executed once only, before the first input record is read (example)BEGINFILE
END
rule is executed once only, after all the input is read (example)ENDFILE
rule :
END
rulessystem(myCommand)
myVariable=system(myCommand)
stores the return code of myCommand into myVariable
0 1
myCommand | getline
awk 'BEGIN { myCommand = "date --iso-8601=seconds" myCommand | getline myResultVariable close(myCommand) print "Current date = "myResultVariable }'
[ -e someFile ] && rm someFile; for i in 1 2; do echo -e 'hello someFile world' | awk '{ print "\ninput : "$0; if(system("[ -f "$2" ]")) { print $2" exists" } }' ls someFile; touch someFile done; rm someFile
for
loop that runs twicesystem
input : hello someFile world someFile exists mmmkay ls: cannot access 'someFile': No such file or directory make up your mind ! input : hello someFile world someFile
success | failure | |
---|---|---|
Awk | anything else | 0 |
Bash | 0 | anything else |
[ -f "$2" ]
is a Bash success : 0system
returns this code as-isif(system(Bash success))
is false
echo | awk '{ if(system("true")) print "ok" }' (nothing) echo | awk '{ if(system("false")) print "ok" }' ok
23a5b5a3d9ba0d2c6277dbdaf2557033 /etc/alternatives/awk 23a5b5a3d9ba0d2c6277dbdaf2557033 /usr/bin/gawk
Once gawk is installed, it can be invoked with awk.
$0
being the whole line itself) :3 4
c averell
line 1: a line 2: b line 3: c line 4: d line 5: e
a.c.e.g
aPLOPcPLOPePLOPg
\n
(NEWLINE
) : by default Awk considers 1 record == 1 line of input~ is the Awk operator to match a regular expression.
logFile='/var/log/lighttpd/www.example.com.log'; resultFile='./result.csv'; tmpFile=$(mktemp --tmpdir tmp.result.XXXXXXXX); grep '" 500 ' $logFile | sed -r 's/^.*GET ([^ ]*).*HTTP\/1\.." ([0-9]*).*$/\1;\2;/' > $tmpFile; cat $tmpFile | sort | uniq -c | sort -nr > $resultFile; rm $tmpFile
Using grep 1st because sed can't find a match on every line, as we're reporting only on HTTP 500 errors.
Awk is a programmable text filter. Its input can be :
{ print $0 }
, albeit correct, is redundant .An Awk script is made of 3 blocks :
Awk reads the input line by line, then applies the specified filter(s) to detect whether or not to process the current line. Before starting processing a line, Awk splits it into fields and stores fields values in $1
(1st field), $2
, ..., $NF
(last field). $0
is the whole input line. The fields separator (specified with FS) defaults either to [SPACE] or [TAB] (details).
There is no need to use grep together with Awk as Awk "RegExp matches" lines to process.
Criteria | select matching lines | select not matching lines |
---|---|---|
line number within input |
awk 'NR==n {doSomething}' c |
a b d |
line vs regular expression |
awk '/regEx/ {doSomething}'
|
awk '!/regEx/ {doSomething}'echo -e 'foo\nbar\nbaz' | awk '!/a/ {print $0}' foo(source, example) |
line vs number of fields |
echo -e 'field1\nfield1\tfield2\nfield1\tfield2\tfield3' | awk 'NF == 2 {print $0}'
field1 field2 |
|
field vs number |
echo -e 'foo\t12\nbar\t34\nbaz\t56' | awk '$2 > 25 {print $0}'
bar 34 baz 56 Awk is smart enough to strip leading zeroes :
Trying to filter data based on line numbers returned by grep -n with a construct like :may fail because of the returned color codes.
|
|
field vs string |
awk '$n == "value" {doSomething}'for i in {1..3}; do echo "foo$i bar$i baz$i"; done | awk '$2 == "bar2" {print $0}' foo2 bar2 baz2 |
awk '$n != "value" {doSomething}'for i in {1..3}; do echo "foo$i bar$i baz$i"; done | awk '$2 != "bar2" {print $0}' foo1 bar1 baz1 foo3 bar3 baz3 |
field vs regular expression |
awk '$n ~ /regEx/ {doSomething}'
|
awk '$n !~ /regEx/ {doSomething}'for i in {1..3}; do echo "foo$i bar$i baz$i"; done | awk '$2 !~ /a.1/ {print $0}' foo2 bar2 baz2 foo3 bar3 baz3 |
field vs regular expression with if / else construct (source) |
for i in {1..3}; do echo "foo$i bar$i baz$i"; done | awk '{ if($2 ~ "a.2") {print "MATCH : "$2 } else {print "NO MATCH"} }'
NO MATCH MATCH : bar2 NO MATCH |
|
several conditions |
awk 'condition1 logicalOperator condition2 logicalOperator ... conditionN {doSomething}'logicalOperator can be (source) :
|
If the numerical value has a unit letter, it doesn't work anymore :
foo 8U ooops !
bar 34U
baz 56U
solution :
bar 34U baz 56U
Try it :
%
/, "", $5)} {if(strtonum($5) > 50) {print $0}}'
awk 'BEGIN { print "trailing unit (single letter) : " strtonum("123U") print "trailing unit (word) : " strtonum("123potatoes") print "leading unit (single letter) : " strtonum("Y123") print "leading unit (word) : " strtonum("banana123") }'
trailing unit (single letter) : 123 OK trailing unit (word) : 123 OK leading unit (single letter) : 0 KO leading unit (word) : 0 KO
Flag | Usage |
---|---|
-F x | use x as the input Field separator
|
-i awkLibrary --include awkLibrary |
load the specified library awkLibrary (example) |
-v variable=value |
|
Exit status | Description |
---|---|
0 aka UNIX_SUCCESS |
No problem during execution, including when no match was found. Check it : a 0 0 |
1 aka UNIX_FAILURE |
An error occurred |
2 |
Fatal error |
printf adds no carriage return after printing. print does.
Then count occurrences :[13-Nov-2013 03:03:35 Europe/Paris] PHP Warning: Memcached::touch(): ... in ....php on line 45 [13-Nov-2013 03:04:42 Europe/Paris] PHP Warning: file_get_contents(http://...): HTTP/1.0 404 Not Found in ...php on line 202 ...let's say you'd like to remove the date/time field to group and count similar errors. To do so :
awk '{ for (i=1;i<=3;i++) $i="";print }' file.log | awk '{sub(/^[ \t]+/, ""); print}' | sort | uniq -c | sort -nr
//
operator to select the matching line :
/stuffToMatch/
'(nothing)
$0 ~ /stuffToMatch/
'(nothing)no match found, as said above
stuffToMatch
'fruit: apple fruit: banana vegetable: carrotmatches everything
$0 ~ stuffToMatch
'fruit: banana vegetable: carrot
$1 ~ stuffToMatch
'vegetable: carrot
$2 ~ stuffToMatch
'fruit: bananaAll examples work as expected
"a"
1a 3a
a
1a 2b 3a 4b
1a 2b 3a 4b
1a 3a
if input =~ "foo.=A"
continue
else
print input
$0 ~ "foo.="value {next} {print}
'$0 ~ "("value"|B)C"
'AC BC
echo -e 'A\tB\tC\tD\nE\tF\tG\tH\n\nI\tJ\tK\tL' | awk '!/^$/ {print $3}'
C G K
value1 value2
/key1|key2/
part of the awk command is a "normal" regular expression alternationprintf $2 " "
part simply prints the 2nd field of each matching line, followed by a space