2016-07-07 39 views
0

我需要使用具有特定名称模式的几个gzip文件的内容创建一个大文本文件。要做到这一点,我用:在find -exec中使用zcat和sed

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很困惑,因为我没有正确指定每个命令结束的位置,但我不知道如何正确执行。

回答

1

-exec需要一个简单的命令及其参数;它不会像管道或重定向一样处理shell构造。您的原始命令是相同的

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

由于壳立即识别输出重定向并识别命令(find)和它的参数之前通过命令行删除。

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

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

这种方法存在一些问题;修复它们需要让sh命令更复杂一些。如果你正在使用bash 4或更高版本,我建议干脆抛弃find和使用shell循环与**水珠沿着:

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

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

+0

谢谢,我想我会用这种方法。 – user3537026

-1

尝试将引号(")围绕参数-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 \; 
+0

谢谢,不幸的是,这导致了以下错误,而不是:'bash:/:是一个目录' '发现:缺少参数给''-exec'' – user3537026