Awk: use inverted string match and then replace characters

I want to extract lines that do not contain # and delete " , ; in the output.

My FILE input looks like this:

 # ;string"1" # string"2"; string"3"; 

You can use grep and tr to get the desired output:

 grep -v '#' FILE | tr -d ';"' string3 

However, I want to use awk .

I can extract the inverse match awk '!/#/' FILE , but how can I use sub to delete " , ; in the same awk command?

+7
awk
source share
4 answers

You can use gsub to globally substitute:

 awk '!/#/{gsub(/[";]/,"",$0);print}' 

In the decrypted form below, this shows the same results as your grep/tr pipeline:

 pax> echo '# ;string"1" # string"2"; string"3";' | awk '!/#/{gsub(/[";]/,"",$0);print}{}' string3 

Note that the final {} may not be needed in some awk implementations, but it is there to stop the output of inconsistent strings in these implementations (usually older ones) that do this automatically for strings that do not match any of the rules.

+5
source share

Use gsub instead to replace all matches with more than just one:

 awk '/#/{next}{gsub(/[";]/,"")}1' file 

Output:

 string3 
  • Skipping the third parameter to gsub makes it handle $0 by default.
  • /#/{next} allows you to skip lines containing #
  • 1 makes print $0
+3
source share

Another version of awk

 awk -F"[\";]" '{$1=$1} !/^#/' OFS= file string3 awk '{gsub(/[";]/,x)} !/^#/' file string3 

x does not represent anything. It is also possible to use "" , but retains one character :)

+2
source share

If you want to give sed chance:

 sed -n '/^[^#]/s/[";]//gp' file string3 
+2
source share

All Articles