Print a list of fields passed as a variable

南笙酒味 提交于 2020-01-14 08:46:12

问题


I have a file say a.txt and below are the contents of it:

bob 1 100            
lincoln 2 200  
chris 3 300        

The file contents are separated by space.

Using awk, I could access each column. Using below command to print 1st and 3rd columns separated by comma:

cat a.txt | awk ' { print $1","$3} '

and I was successful.

Now I want to pass the criteria dynamically from another shell script. By saying criteria I mean - $1","$3.

I tried the below command but it didn't work.

myvar="$1"   
awk -v a="$myvar"  ' { print a } ' a.txt

but this is printing $1 3 times as there are three rows in a.txt.

How can I pass a list of fields to awk in this way?


回答1:


The problem here is that the $ in the variable you have passed to awk is interpreted literally - it cannot be used to refer to a specific field.

For a single field, you could use something like this:

awk -v field=1 '{ print $field }' file
bob
lincoln
chris

For multiple fields, this is a little more complicated:

awk -v fields="1 3" 'BEGIN{ n = split(fields,f) }
    { for (i=1; i<=n; ++i) printf "%s%s", $f[i], (i<n?OFS:ORS) }' file
bob 100
lincoln 200
chris 300

The list of fields is passed as a string, which is split into an array. The array is then looped through, using printf to output each field, followed by either the Output Field Separator OFS or the Output Record Separator ORS, depending on whether it's the last field or not. To separate the fields with a comma, you can pass -v OFS=, as an option.




回答2:


Alternative to awk solution using cut which already accepts field positions via comma separated list.

cols="1,3"; cut -d" " -f"$cols" a.txt

for comma separated output pipe to tr ' ' ',' or use --output-delimiter="," cut option.

Note that this will give you the flexibility to specify input as closed or open range such as 1-3 or 2-




回答3:


You will need to pass a delimited string to awk and inside awk use split to split on that delimiter.

Something like this should work:

awk -v search='1,3' 'BEGIN{split(search, a, ",")}
               {f=""; for (i=1;i in a;i++) {printf "%s%s", f, $a[i]; f=OFS} print ""}' file

Output:

bob 100
lincoln 200
chris 300


来源:https://stackoverflow.com/questions/32396788/print-a-list-of-fields-passed-as-a-variable

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!