Return two variables in awk?

Up vote 0 down vote favorite share g+ share fb share tw.

At the moment here is what im doing ret=$(ls -la | awk '{print $3 " " $9}') usr=$(echo $ret | awk '{print $1}') fil=$(echo $ret | awk '{print $2}') The problem is that im not running an ls im running a command that takes time, so you can understand the logic. Is there a way I can set the return value to set two external values, so something such as ls -la | awk -r usr=x -r fil=y '{x=$3; y=$9}' This way the command will be run once and I can minimize it to one line bash shell awk link|improve this question edited Jan 25 at 11:15 asked Jan 25 at 11:07Angel.King.471,1061931 99% accept rate.

Parsing ls should be punishable by death. Mywiki.wooledge.org/ParsingLs – Daniel Kamil Kozar Jan 25 at 11:09 like I said im not actually parsing ls its just there as an example to get my point accross. Sorry I didn't make that clear – Angel.King.47 Jan 25 at 11:14 Still.

Don't ever let that idea get to your head. Also, I act this way every time I see $(ls | awk) or anything of this sort. – Daniel Kamil Kozar Jan 25 at 11:18.

A workaround using read usr="" fil="" while read you f; do usr="$usr\n$u"; fil="$fil\n$f"; done $(ls -la | awk '{print $3 " " $9}') > EOF.

Im using bash at the moment – Angel.King.47 Jan 25 at 11:37 1 Omg very smart idea. Thanks :D – Angel.King.47 Jan 25 at 11:41 I still like this way better, Thanks – Angel.King.47 Jan 25 at 11:42.

It's not pretty, but if you really need to do this in one line you can use awk/bash's advanced meta-programming capabilities :) eval $(ls -la | awk '{usr = $3 " " usr;fil = $9 " " fil} END{print "usr=\""usr"\";fil=\""fil"\""}') To print: echo -e $usr echo -e $fil Personally, I'd stick with what you have - it's much more readable and performance overhead is tiny compared to the above: $time real 0m0.017s user 0m0.006s sys 0m0.011s $time real 0m0.009s user 0m0.004s sys 0m0.007s.

1 Very good approach. But how could we update your code to allow $usr and $fil contain the list of all users and all filenames? (this first version gives solely the last user / filename).

– oHessling Jan 25 at 12:02 1 I have just changed your code to catch all the users/files, not only the last pair. Please, could you perform again your benchmark? Now, the time results should be comparable... – oHessling Jan 25 at 12:35 eval is also a good idea, didn't think of that at all +1 – Angel.King.47 Jan 25 at 13:15 Thanks - misunderstood the original req!

Have updated based on oHessling's excellent edit (with a minor tweak). Cheers! – bob Jan 25 at 13:22.

Using bash v4 associative array: unset FILES declare -A FILES FILES=( ls -la | awk '{print $9 " " $3}' ) Print the list of owner & file: for fil in ${! FILES@} do usr=${FILES"$fil"} echo -e "$usr" "\t" "$fil" done My apologies, I cannot test on my computer because my bash v3.2 does not support associative array :-(. Please, report any issue...

The accepted answer uses process substitution, which is a bashism that only works on certain platforms. A more portable solution is to use a heredoc: read you f Note that it requires the shell to read all of the output of the program into memory, so is not suitable if the output is expected to be large or if the process is long running.

1 Yes you are right => I have then completed my answer. Thank you ;-) – oHessling Jan 25 at 14:12.

You could use a bash array or the positional parameters as temporary holding place: ret_ary=( $(command | awk '{print $3, $9}') ) usr=${ret_ary0} fil=${ret_ary1} set -- $(command | awk '{print $3, $9}') usr=$1 fil=$2.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions