Assign a Shell variable in AWK

11,045

Solution 1

There are a number of issues, but let's isolate problems and tackle them one at a time.

Given - Raw string:

/home/rm/home-scripts/originals/audicerttest/incoming/TEST040511.txt

Desired Output - You want this part to be saved in a variable:

audicerttest/incoming

How-To - This will do it:

string="/home/rm/home-scripts/originals/audicerttest/incoming/TEST040511.txt"
parsed=$(awk 'BEGIN{FS=OFS="/"} {print $6, $7}' <<< ${string})

In general, suppose you have a file called input_file.txt:

/home/rm/home-scripts/originals/audicerttest/incoming/TEST040511.txt
/home/rm/home-scripts/originals/audicerttest2/incoming/TEST040512.txt
/home/rm/home-scripts/originals/audicerttest3/incoming/TEST040513.txt

You can do:

awk 'BEGIN{FS=OFS="/"} {print $6, $7}' input_file.txt > parsed_vars.txt

And parsed_vars.txt will contain:

audicerttest/incoming
audicerttest2/incoming
audicerttest3/incoming

Some explanations:

  • parsed=$(...) - spawn a subshell and save the output to stdout within that subshell to the variable parsed
  • awk 'BEGIN{FS=OFS="/"} - invoke awk and set delimiter as / for both input and output.
  • {print $6, $7}' - based on the format of your raw strings, you want to print the 6th (audicerttest) and the 7th (incoming) fields.
  • <<< ${string} is the notation for using herestring
  • input_file.txt > parsed_vars.txt - read from specified input file, and redirect output to an output file.

Solution 2

Here's a pure bash solution, not using any overkill awk and not using any evil eval and not using any subshells:

You have this string:

string="/home/rm/home-scripts/originals/audicerttest/incoming/TEST040511.txt"

You want a string that contains the 5th and 6th fields (where separation is /) in a variable parsed. Let's go:

IFS=/ a=( $string ) printf -v parsed '%s/%s' "${a[@]:5:2}"

Solution 3

echo ${file} | eval $(awk '{split($0,a,"/"); print "abc=a[6]/a[7]"}' < /dev/null)

Okay, a couple of problems here.

awk is reading from /dev/null, which doesn't make any sense, guess you want to process the filename:

echo {$file} | awk ... 

"a[6]" is the string a[6], no substitution is made.

Now eval the whole thing:

eval $(echo $file | awk '{split($0,a,"/"); print "abc="a[6]"/"a[7]""}')

Finally, eval is evil, why don't you directly set the variable?

abc=$(echo $file | awk '{split($0,a,"/"); print a[6]"/"a[7]}')

On a personal note, I thing this is a bit more clear:

 cut -d / --output-delimiter / -f6,7

Solution 4

With only bash arrays, you could do the following:

Assuming:

path=/home/rm/home-scripts/originals/audicerttest/incoming/TEST040511.txt

Then:

IFS=/ split=(${path})
path_part="${split[5]}/${split[6]}"

$split will be an array, with element 0 empty, element one home, element 2 rm, etc. With that you just need to concatenate the elements you want to get the part you like.

Share:
11,045
Ravi
Author by

Ravi

Updated on June 04, 2022

Comments

  • Ravi
    Ravi almost 2 years

    I have strings like this

    /home/rm/home-scripts/originals/audicerttest/incoming/TEST040511.txt
    /home/rm/home-scripts/originals/audicerttest2/incoming/TEST040512.txt
    /home/rm/home-scripts/originals/audicerttest3/incoming/TEST040513.txt
    

    etc..I want to extract strings 'audicerttest/incoming', audicerttest2/incoming' etc into a shell variable and use it later in the script. I tried something like this.

    for file in `find ${ROOT}/* -type f | grep -v -f test.txt`
    do
    let count++
    echo ${count}: ${file}
    echo ${file} | eval $(awk '{split($0,a,"/"); print "abc=a[6]/a[7]"}' < /dev/null)
    echo abc====$abc
    done
    

    but its not giving any output for abc.

  • gniourf_gniourf
    gniourf_gniourf over 11 years
    The main problem in your method is the useless use of eval. eval is evil! Not mentioning the useless uses of subshells.
  • Karoly Horvath
    Karoly Horvath over 11 years
    I was just updating my answer... He is using an inefficient tool for the task, but (I hope) he's asking about why it didn't work, an not just asking for an other solution. So, no idea why the downvote.
  • Ravi
    Ravi over 11 years
    I'm a total newbie to Shell. I agree there are too many mistakes. Thanks for correcting those.