tgwtdt
tgwtdt

Reputation: 362

How to combine these awk commands?

Can someone please explain to me how I can combine these piped awks to a single awk?

awk 'match($0, /(,|^)[^,]*shalvar[^,]*(,|$)/) {
  print substr($0, RSTART, RLENGTH)}' file.txt |
awk 'gsub(",","")' | awk '{$1=$1};1'

I try this but it doesn't work:

awk 'match($0, /(,|^)[^,]*shalvar[^,]*(,|$)/) {
  gsub(",","");$1=$1;print substr($0, RSTART, RLENGTH)}' file.txt

I understand that it shouldn't work because the characters are removed but the pointers don't change. How can I fix it now?

Upvotes: 1

Views: 93

Answers (1)

tripleee
tripleee

Reputation: 189297

You need to wrap things the other way around. Collect the string you want to extract, then do the manipulations on the extracted value, just like your original script with multiple Awk scripts in a pipeline did.

awk 'match($0, /(,|^)[^,]*shalvar[^,]*(,|$)/) {
  g=substr($0, RSTART, RLENGTH);
  gsub(",","",g);
  # $1=$1 is nice but we cannot use that here; here is a workaround
  gsub(/^ *| *$/, "", g);
  print g}' file.txt

The shortcut $1=$1 for trimming whitespace around a value works in an isolated Awk script if you are confident that there is only one field, but here, we don't necessarily have a single field (or do we?) so I use a more general solution to explicitly trim whitespace around the extracted string which also avoids relying on a well-known but still obscure side effect.

If shalvar is actually a variable you want to receive from the shell like $foo , try

awk -v field="$foo" 'match($0, "(^|,)[^,]*" field "[^,]*(,|$)") {
    ...

to interpolate the variable into a string which is then applied as a regular expression.

Upvotes: 2

Related Questions