bash awk 返回两个变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9001668/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 21:34:34  来源:igfitidea点击:

Return two variables in awk

bashshellawk

提问by Angel.King.47

At the moment here is what im doing

目前这是我在做什么

ret=$(ls -la | awk '{print  " "  }')
usr=$(echo $ret | awk '{print }')
fil=$(echo $ret | awk '{print }')

The problem is that im not running an lsim running a command that takes time, so you can understand the logic.

问题是我没有运行一个ls需要时间的命令,所以你可以理解逻辑。

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=; y=}'

This way the command will be run once and i can minimize it to one line

这样命令将运行一次,我可以将其最小化为一行

采纳答案by olibre

A workaround using read

使用的解决方法 read

usr=""
fil=""
while read u f; do usr="$usr\n$u"; fil="$fil\n$f"; done < <(ls -la | awk '{print  " "  }')

For performance issue you could use <<<, but avoid it if the returned text is large:

对于性能问题,您可以使用<<<,但如果返回的文本很大,请避免使用:

while read u f; do usr="$usr\n$u"; fil="$fil\n$f"; done <<< $(ls -la | awk '{print  " "  }')

A more portable way inspired from @WilliamPursell's answer:

一种更便携的方式,灵感来自@WilliamPursell 的回答:

$ usr=""
$ fil=""
$ while read u f; do usr="$usr\n$u"; fil="$fil\n$f"; done << EOF
> $(ls -la | awk '{print  " "  }')
> EOF

回答by bob

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 :)

它并不漂亮,但如果您真的需要在一行中完成此操作,您可以使用awk/bash的高级元编程功能:)

eval $(ls -la | awk '{usr =  " " usr;fil =  " " 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 <three line approach>

real    0m0.017s
user    0m0.006s
sys     0m0.011s

$time <one line approach>
real    0m0.009s
user    0m0.004s
sys     0m0.007s

回答by Perennial

What you want to do is capture the output of ls or any other command and then process it later.

您想要做的是捕获 ls 或任何其他命令的输出,然后再进行处理。

ls=$(ls -l)
first=$(echo $ls | awk '{print }')
second=$(echo $ls | awk '{print }')

回答by olibre

Using bashv4 associative array:

使用bashv4关联数组

unset      FILES
declare -A FILES
FILES=( ls -la | awk '{print  " "  }' )

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 bashv3.2 does not support associative array:-(. Please, report any issue...

抱歉,我无法在我的计算机上进行测试,因为我的bashv3.2 不支持关联数组:-(。请报告任何问题...

回答by William Pursell

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:

接受的答案使用进程替换,这是一种仅适用于某些平台的 bashism。更便携的解决方案是使用 heredoc:

read u f << EOF
$( ls ... )
EOF

It is tempting to try:

尝试以下方法很诱人:

ls ... | read u f

but the read then runs in a subshell. A common technique is:

但是读取然后在子shell中运行。一种常见的技术是:

ls ... | { read u f; # use $u and $f here; }

but to make the variables available in the remainder of the script, the interpolated heredoc is the most portable approach. 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.

但是为了使脚本的其余部分中的变量可用,插入的 heredoc 是最便携的方法。请注意,它需要 shell 将程序的所有输出读入内存,因此如果预期输出很大或进程长时间运行,则不适合。

回答by glenn Hymanman

You could use a bash array or the positional parameters as temporary holding place:

您可以使用 bash 数组或位置参数作为临时保存位置:

ret_ary=( $(command | awk '{print , }') )
usr=${ret_ary[0]}
fil=${ret_ary[1]}

set -- $(command  | awk '{print , }')
usr=
fil=