在 find -exec 中使用 zcat 和 sed
Using zcat and sed in find -exec
我需要使用几个具有特定名称模式的 gzip 文件的内容创建一个大文本文件。为此,我使用了:
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 很困惑,因为我没有正确指定每个命令的结束位置,但我不知道如何正确执行。
尝试在 -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 \;
-exec
接受一个简单的命令及其参数;它根本不处理 shell 构造,如管道或重定向。您的原始命令与
相同
find . -name '*dna.toplevel.txt.gz' -exec zcat {} \; >> all.txt
因为 shell 会立即识别输出重定向并在识别命令 (find
) 及其参数之前将其从命令行中删除。
由于 sed
需要来自 find
的文件名作为其命令的一部分,因此您需要 运行 将管道作为参数的 shell 通过-c
选项。
find . -name '*dna.toplevel.txt.gz' -exec \
sh -c "zcat {} | sed 's/>/>{}|/g'" \; >> all.txt
这种方法有一些问题;修复它们需要使 sh
命令变得相当复杂。如果您使用 bash
4 或更高版本,我建议完全放弃 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
不包含任何 |
个字符;如果是这样,您需要选择不同的分隔符。
我需要使用几个具有特定名称模式的 gzip 文件的内容创建一个大文本文件。为此,我使用了:
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 很困惑,因为我没有正确指定每个命令的结束位置,但我不知道如何正确执行。
尝试在 -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 \;
-exec
接受一个简单的命令及其参数;它根本不处理 shell 构造,如管道或重定向。您的原始命令与
find . -name '*dna.toplevel.txt.gz' -exec zcat {} \; >> all.txt
因为 shell 会立即识别输出重定向并在识别命令 (find
) 及其参数之前将其从命令行中删除。
由于 sed
需要来自 find
的文件名作为其命令的一部分,因此您需要 运行 将管道作为参数的 shell 通过-c
选项。
find . -name '*dna.toplevel.txt.gz' -exec \
sh -c "zcat {} | sed 's/>/>{}|/g'" \; >> all.txt
这种方法有一些问题;修复它们需要使 sh
命令变得相当复杂。如果您使用 bash
4 或更高版本,我建议完全放弃 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
不包含任何 |
个字符;如果是这样,您需要选择不同的分隔符。