0

我需要使用几个具有特定名称模式的压缩文件的内容来创建一个大文本文件。为此,我使用了:

find . -name '*dna.toplevel.txt.gz' -exec zcat {} >> all.txt \;

它工作得很好。问题是,现在我需要即时编辑文本以用“文件名|”替换特定字符“>”。我设法煮了这个:

find . -name '*dna.toplevel.txt.gz' -exec zcat {} | sed 's/>/>{}|/g' >> all.txt \;

但我收到以下错误:

  • sed:无法读取;:没有这样的文件或目录
  • 查找:缺少“-exec”的参数

我理解糟糕的 bash 很困惑,因为我没有正确指定每个命令的结束位置,但我不知道如何正确执行。

4

2 回答 2

1

-exec接受一个简单的命令及其参数;它根本不处理管道或重定向等外壳结构。您的原始命令与

find . -name '*dna.toplevel.txt.gz' -exec zcat {} \; >> all.txt

find因为 shell 会立即识别输出重定向,并在识别命令 ( ) 及其参数之前将其从命令行中删除。

由于sed需要将文件名find作为其命令的一部分,因此您需要运行一个外壳程序,该外壳程序通过-c选项将管道作为参数。

find . -name '*dna.toplevel.txt.gz' -exec \
  sh -c "zcat {} | sed 's/>/>{}|/g'" \; >> all.txt

这种方法存在一些问题;修复它们需要使sh命令变得相当复杂。如果您使用的是bash4 或更高版本,我建议您完全放弃find并使用 shell 循环和**glob:

shopt -s globstar
for f in ./**/*dna.toplevel.txt.gz; do
    zcat "$f" | sed "s|>|>$f|g"
done >> all.txt

如果此命令正在创建all.txt,您可以简单地使用>而不是>>。这也假设$f不包含任何|字符;如果是这样,您将需要选择不同的分隔符。

于 2016-07-07T14:47:04.100 回答
0

尝试将引号 ( ") 放在 的参数周围-exec

find . -name '*dna.toplevel.txt.gz' -exec "zcat {} | sed 's/>/>{}|/g'" >> all.txt \;

您需要逃离管道:

find . -name '*dna.toplevel.txt.gz' -exec zcat {} \| sed 's/>/>{}|/g' >> all.txt \;
于 2016-07-07T14:17:54.703 回答