How to replace the nth column/field in a comma-sep

2019-01-25 12:16发布

问题:

assume I have a string

"1,2,3,4"

Now I want to replace, e.g. the 3rd field of the string by some different value.

"1,2,NEW,4"

I managed to do this with the following command:

echo "1,2,3,4" | awk -F, -v OFS=, '{$3="NEW"; print }'

Now the index for the column to be replaced should be passed as a variable. So in this case

index=3

How can I pass this to awk? Because this won't work:

echo "1,2,3,4" | awk -F, -v OFS=, '{$index="NEW"; print }'
echo "1,2,3,4" | awk -F, -v OFS=, '{$($index)="NEW"; print }'
echo "1,2,3,4" | awk -F, -v OFS=, '{\$$index="NEW"; print }'

Thanks for your help!

回答1:

Have the shell interpolate the index in the awk program:

echo "1,2,3,4" | awk -F, -v OFS=, '{$'$index'="NEW"; print }'

Note how the originally single quoted awk program is split in three parts, a single quoted beginning '{$', the interpolated index value, followed by the single quoted remainder of the program.



回答2:

This might work for you:

index=3 
echo "1,2,3,4" | awk -F, -v OFS=, -v INDEX=$index '{$INDEX="NEW"; print }'

or:

index=3 
echo "1,2,3,4" | sed 's/[^,]*/NEW/'$index


回答3:

Here's a seductive way to break the awkwardness:

$ echo "1,2,3,4" | sed 's/,/\n/g' | sed -e $index's/.*/NEW/'

This is easily extendable to multiple indexes just by adding another -e $newindex's/.*/NEWNEW/'



回答4:

# This should be faster than awk or sed.
str="1,2,3,4"
IFS=','
read -a f <<< "$str"
f[2]='NEW'
printf "${f[*]}"


回答5:

With plain awk (I.E. Not gawk etc) I believe you'll have to use split( string, array, [fieldsep] ); change the array entry of choice and then join them back together with sprintf or similar in a loop.

gawk allows you to have a variable as a field name, $index in your example. See here.

gawk is usually the default awk on Linux, so change your invocation to gawk "script" and see if it works.