sj7*_*755 31 shell grep bash pipe
我有一个应用程序会产生大量我不想存储到磁盘上的数据。该应用程序主要输出我不想使用的数据,而是一组必须拆分为单独文件的有用信息。例如,给定以下输出:
JUNK
JUNK
JUNK
JUNK
A 1
JUNK
B 5
C 1
JUNK
Run Code Online (Sandbox Code Playgroud)
我可以像这样运行应用程序三次:
./app | grep A > A.out
./app | grep B > B.out
./app | grep C > C.out
Run Code Online (Sandbox Code Playgroud)
这会让我得到我想要的,但需要太长时间。我也不想将所有输出转储到一个文件中并通过它进行解析。
有没有什么方法可以将上面显示的三个操作组合在一起,这样我只需要运行一次应用程序,仍然可以获得三个单独的输出文件?
Aur*_*oms 80
如果你有T 恤
./app | tee >(grep A > A.out) >(grep B > B.out) >(grep C > C.out) > /dev/null
Run Code Online (Sandbox Code Playgroud)
(从这里)
(关于进程替换)
Rah*_*til 32
您可以使用 awk
./app | awk '/A/{ print > "A.out"}; /B/{ print > "B.out"}; /C/{ print > "C.out"}'
Run Code Online (Sandbox Code Playgroud)
ter*_*don 17
您还可以使用 shell 的模式匹配功能:
./app | while read line; do
[[ "$line" =~ A ]] && echo $line >> A.out;
[[ "$line" =~ B ]] && echo $line >> B.out;
[[ "$line" =~ C ]] && echo $line >> C.out;
done
Run Code Online (Sandbox Code Playgroud)
甚至:
./app | while read line; do for foo in A B C; do
[[ "$line" =~ "$foo" ]] && echo $line >> "$foo".out;
done; done
Run Code Online (Sandbox Code Playgroud)
一种更安全的方法,可以处理以 开头的反斜杠和行-
:
./app | while IFS= read -r line; do for foo in A B C; do
[[ "$line" =~ "$foo" ]] && printf -- "$line\n" >> "$foo".out;
done; done
Run Code Online (Sandbox Code Playgroud)
正如@StephaneChazelas 在评论中指出的那样,这不是很有效。最好的解决方案可能是@AurélienOoms'。
如果您有多个内核并且希望进程并行,则可以执行以下操作:
parallel -j 3 -- './app | grep A > A.out' './app | grep B > B.out' './app | grep C > C.out'
Run Code Online (Sandbox Code Playgroud)
这将在并行内核中产生三个进程。如果您希望有一些输出到控制台或主文件,它的优点是将输出保持在某种顺序,而不是混合它。
Ole Tange的 gnu 实用程序parallel可以从名称为parallel或moreutils 的大多数存储库中获得。来源可以从Savannah.gnu.org获得。另外一个介绍教学视频是在这里。
附录
使用更新版本的并行(不一定是您的发行版存储库中的版本),您可以使用更优雅的构造:
./app | parallel -j3 -k --pipe 'grep {1} >> {1}.log' ::: 'A' 'B' 'C'
Run Code Online (Sandbox Code Playgroud)
这实现了在单独的内核或线程中运行一个 ./app 和 3 个并行 grep 进程的结果(由并行本身决定,也认为 -j3 是可选的,但在本示例中提供它是出于指导目的)。
可以通过执行以下操作获得更新版本的并行:
wget http://ftpmirror.gnu.org/parallel/parallel-20131022.tar.bz2
Run Code Online (Sandbox Code Playgroud)
然后通常的解压,cd到parallel-{date},./configure && make,sudo make install。这将安装 parallel、man page parallel 和 man page parallel_tutorial。
小智 7
这是 Perl 中的一个:
./app | perl -ne 'BEGIN {open(FDA, ">A.out") and
open(FDB, ">B.out") and
open(FDC, ">C.out") or die("Cannot open files: $!\n")}
print FDA $_ if /A/; print FDB $_ if /B/; print FDC $_ if /C/'
Run Code Online (Sandbox Code Playgroud)