Assign a Shell variable in AWK
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 tostdout
within that subshell to the variableparsed
-
awk 'BEGIN{FS=OFS="/"}
- invokeawk
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.
Ravi
Updated on June 04, 2022Comments
-
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 over 11 yearsThe main problem in your method is the useless use of
eval
.eval
is evil! Not mentioning the useless uses of subshells. -
Karoly Horvath over 11 yearsI 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 over 11 yearsI'm a total newbie to Shell. I agree there are too many mistakes. Thanks for correcting those.