【问题标题】:Pipe multiple files (gz) into C program将多个文件(gz)通过管道传输到 C 程序中
【发布时间】:2010-03-20 22:39:10
【问题描述】:

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

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

我该怎么做?

【问题讨论】:

  • 请注意,gzip 附带一个gzcat 程序,它等效于gunzip -c

标签: c++ c shell pipe gunzip


【解决方案1】:

不需要shell循环:

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

使用“-cd”选项,gzip 会将文件列表解压缩到标准输出(或者您可以使用“gunzip -c”)。 $(&lt;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

【讨论】:

  • 感谢您提供的所有优秀示例,非常有用的参考
【解决方案2】:

你应该可以得到一个gunzip进程解压多个文件。

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

zcat 是在许多系统上调用gunzip -c 的另一种方式,它与cat 类似;但如果您的系统的zcat 实际上是uncompress,请检查gzcat。)

您也可以使用子外壳。

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

【讨论】:

  • 注意:zcat 最初与产生 '.z' 文​​件的 'pack' 和 'unpack' 相关联。这些天来,幸运的是,它们是过去的遗物——它们效率不高(甚至比生成“.Z”文件的“压缩”和“解压缩”还要低。名义上,您要查找的命令是“gzcat” ';然而,'zcat' 等价于 'gzcat' 的情况并不少见。
  • @Jonathan Leffler:好点子,看来我使用现代 linux 有点太多了。
  • for 循环的括号是可选的,bash 足够聪明。
  • @Giuseppe Guerrini:是的,在这种情况下它们不是必需的,因为for 循环是一个命令。在更一般的情况下,子外壳可能很有用。
  • 我说错了:它是打包、解包和 pcat;它是压缩、解压缩和 zcat。 Gzip 当然可以处理 .Z 文件的解压缩;现在,您很难找到由 pack 生成的 .z 文件(尽管最早的 gzip 版本使用该扩展名,直到混淆被认为是不可接受的)。 (我刚刚在我的机器上发现了一些文件,在 1990 年进行了 gzip 压缩,后缀为“.z”。)
【解决方案3】:

这是一个shell问题。但是你可以这样做:

cat file* | your_program

for i in file*; do gunzip -c $i; done | your_program

【讨论】:

  • 这是我要输入的内容,不过为了清楚起见,我会添加括号:( for i in file*; ...; done ) | ./a.out
【解决方案4】:

xargs 是你的朋友

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

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

【讨论】:

    【解决方案5】:

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

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

    希望对你有帮助 问候

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多