0

我编写了一个 C 程序,当我使用标准输入将数据通过管道传输到我的程序时,它可以工作,例如:

gunzip -c IN.gz|./a.out

如果我想在文件列表上运行我的程序,我可以执行以下操作:

for i `cat list.txt`
do
  gunzip -c $i |./a.out
done

但这将启动我的程序“文件数”次。我有兴趣将所有文件通过管道传输到同一个进程运行中。

喜欢做

for i `cat list.txt`
do
  gunzip -c $i >>tmp
done
cat tmp |./a.out

我怎样才能做到这一点?

4

5 回答 5

2

不需要 shell 循环:

gzip -cd $(<list.txt) | ./a.out

使用 ' -cd' 选项,gzip 会将文件列表解压缩到标准输出(或者您可以使用 ' gunzip -c')。该$(<file)符号将命名文件的内容扩展为参数列表,而不启动子进程。等价于$(cat list.txt)其他。

但是,如果您觉得必须使用循环,则只需将循环的输出通过管道传输到程序的单个实例中:

for i in `cat list.txt`
do
    gunzip -c $i
done |
./a.out

如果循环的内容更复杂(而不是简单地压缩单个文件),这可能是必要的。您还可以使用 ' { ... }' I/O 重定向:

{
cat /etc/passwd /etc/group
for i in `cat list.txt`
do
    gunzip -c $i
done
} |
./a.out

或者:

{
cat /etc/passwd /etc/group
for i in `cat list.txt`
do
    gunzip -c $i
done; } |
./a.out

注意分号;大括号是必要的。在此示例中,它与使用带括号的正式子 shell 基本相同:

(
cat /etc/passwd /etc/group
for i in `cat list.txt`
do
    gunzip -c $i
done
) |
./a.out

或者:

( cat /etc/passwd /etc/group
  for i in `cat list.txt`
  do
      gunzip -c $i
  done) |
./a.out

注意这里没有分号;不需要。外壳有时非常狡猾。当您需要在管道符号之后对命令进行分组时,大括号 I/O 重定向会很有用:

some_command arg1 arg2 |
{
first sub-command
second command
for i in $some_list
do
    ...something with $i...
done
} >$outfile 2>$errfile
于 2010-03-20T22:53:55.357 回答
2

您应该能够让一个gunzip进程解压缩多个文件。

zcat $(cat list.txt) | ./a.out

zcat是调用gunzip -c许多系统的另一种方式,并显示与 的平行cat;但请检查gzcat您的系统zcat是否实际上是uncompress。)

或者,您可以使用子外壳。

(
  for i in $(cat list.txt)
  do
    gunzip -c "$i"
  done
) | ./a.out
于 2010-03-20T22:44:13.287 回答
1

这是一个空壳问题。但是AFAIK你可以这样做:

cat file* | your_program

或者

for i in file*; do gunzip -c $i; done | your_program
于 2010-03-20T22:46:21.177 回答
0

如果您的程序不需要知道特定输入何时结束而另一个输入何时开始,您可以这样做:

for i `cat list.txt`
do
  gunzip -c $i
done |./a.out

我希望它会帮助你问候

于 2010-03-20T22:45:04.943 回答
0

xargs 是你的朋友

% 猫列表.txt | xargs gunzip -c | ./a.out

如果 list.txt 中的文件中有空格,那么您需要经过一些额外的步骤。

于 2010-03-28T14:44:40.110 回答