4

I'm trying to use awk to pull some different fields from a string.

Example:

selected="a2.flac|a3.flac|a4.flac"
first_file=$(echo "$selected" | awk -F'|' '{print $1}')

The above code returns a2.flac which is what I expected. But now, I want to iterate over a variable and pull each file out one at a time. So I tried this:

i=1
first_file=$(echo "$selected" | awk -F'|' '{print $i}')

I thought this would pull out the first file ... but nothing returns. so I tried this next:

i=1
first_file=$(echo "$selected" | awk -F'|' '{print \$i}')

This also did not work. I also tried this method:

i=1
first_file=$(echo "$selected" | awk -F'|' n=$i '{print $n}')

And also tried this:

i=1
first_file=$(echo "$selected" | awk -v -F'|' n=$i '{print $n}')

Nothing I've tried seems to work. I'm at a loss on what will work.

3 Answers 3

4

Your $i is a shell variable, awk has no access to it so $i evaluates to empty. You can either i) use double qupted for the awk script so that the shell expands variables within it before passing it to awk for execution or ii) pass it to awk as an awk variable:

  • Use double quotes. Note that since the shell is now expanding variables, you'll need to escape the first $ so that it is passed to awk and not interpreted by the shell:

    $ i=1
    $ first_file=$(echo "$selected" | awk -F'|' "{print \$$n}")
    $ echo "$first_file"
    a2.flac
    
  • Pass the variable to awk. You had the syntax almost right:

    $ first_file=$(echo "$selected" | awk -F'|' -vi="$i" '{print $i}')
    $ echo "$first_file"
    a2.flac
    
3

you almost make it

i=1
first_file=$(echo "$selected" | awk -v n="$i" -F'|'  '{print $n}')
  • variable are set using -v name=value
1
  • the above solution is working nicely for me. Based upon the solutions here, I have found a third solution that is also working (but a little convoluted): ` input_file=$(echo "$selected" | awk -F'|' "{print $\"$i\"}")`
    – daniel
    Commented Oct 9, 2015 at 14:22
2

The value of $i is set by the shell, to be able to do that, the string must be either double quoted or unquoted. Thus, your line:

i=1; first_file=$(echo "$selected" | awk -F'|' '{print $i}')     # original
i=1; first_file=$(echo "$selected" | awk -F'|' '{print $'$i'}')  # un-quoted
i=1; first_file=$(echo "$selected" | awk -F'|' '{print $'"$i"'}') # double-quoted
i=1; first_file=$(echo "$selected" | awk -F'|' "{print \$$i}")  # full double-quoted

Of course, you could, and is the most correct way to do it, tell awk what is the value of the var, and use it ( I used jj to make the difference in variable names explicit):

i=1; first_file=$(echo "$selected" | awk -F'|' -v jj="$i" '{print $jj}') 

Perhaps a more idiomatic way will be (no sub-shell because of pipe "|"):

i=1; first_file="$( <<<"$selected" awk -F\| '{print $'$i'}')"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .