我有一个类似
的awk脚本awk 'FNR==NR {col1[$1]++; col2[$2]++; next} {print $0, col2[$2] "/" length(col1)}' input input
但是如果我有很多文件,需要将这个脚本用于连接文件,如:
cat *all_input | awk 'FNR==NR {col1[$1]++; col2[$2]++; next} {print $0, col2[$2] "/" length(col1)}' STDIN STDIN
不起作用。如何从管道中使用STDIN两次?
答案 0 :(得分:4)
您不需要使用烟斗。如果您使用bash
使用process-substitution as <(cmd)
,即实现重定向,其中进程的输入或输出(某些命令序列)显示为临时文件。
awk 'FNR==NR {col1[$1]++; col2[$2]++; next} {print $0, col2[$2] "/" length(col1)}' <(cut -f3 5- input) <(cut -f3 5- input)
答案 1 :(得分:2)
How to use STDIN twice from pipe
的答案是“你不能”。如果你想要使用stdin中的数据两次,那么当你第一次读它时需要将它保存到某个地方,这样你下次就可以使用它。例如:
$ seq 3 |
awk '
BEGIN {
if ( ("mktemp"|getline line) > 0) tmp=line; else exit
ARGV[ARGC]=tmp; ARGC++
}
NR==FNR { print > tmp }
{ print FILENAME, NR, FNR, $0 }
' -
- 1 1 1
- 2 2 2
- 3 3 3
/var/folders/11/vlqr7jmn6jj3fglyl12lj0l00000gn/T/tmp.Y03l9pS7 4 1 1
/var/folders/11/vlqr7jmn6jj3fglyl12lj0l00000gn/T/tmp.Y03l9pS7 5 2 2
/var/folders/11/vlqr7jmn6jj3fglyl12lj0l00000gn/T/tmp.Y03l9pS7 6 3 3
或者您可以将其存储在内部数组或字符串中,稍后再从中读取。
话虽如此,您的具体问题并不需要任何花哨的东西,只需简单:
cat *all_input | awk 'FNR==NR {col1[$1]; col2[$2]++; next} {print $0, col2[$2] "/" length(col1)}' - *all_input
会这么做但除非您的文件非常庞大,否则您真正需要的是存储在阵列中的方法:
awk '{ col1[$1]; col2[$2]++; f0[NR]=$0; f2[NR]=$2 }
END {
for (nr=1; nr<=NR; nr++) {
print f0[nr], col2[f2[nr]] "/" length(col1)
}
}' *all_input
答案 2 :(得分:0)
我不知道这是否有帮助因为我不是awk专家,但任何Linux应用程序(包括awk)都可以直接从 / proc / self / fd / 0 读取stdin
请注意,这比open(0)更不便携,只能在具有可读procfs的Linux上运行(几乎所有的Linux发行版)。
如果应用程序允许并行文件描述符消耗,则可以打开该文件描述符两次并从中读取两次。
路径中的self 指定访问应用程序的PID。