我有一个命令,为CSV文件中的每一行获取一个文件路径:
awk -F, 'NR>0 {print "/mnt/datagenetique/ANALYSIS/Infectiologie/COVID-WGS/Analyse/" $2 "_*/dragen-covidseq/" $1 "_*_ds*/consensus/*.consensus_hard_masked_sequence.fa"}' input.csv
input.csv文件示例:
2071404446,RUN111
2071405093,RUN111
2071405134,RUN111
此命令之后的详细示例:
/mnt/datagenetique/ANALYSIS/Infectiologie/COVID-WGS/Analyse/RUN111_*/dragen-covidseq/2071404446_*_ds*/consensus/*.consensus_hard_masked_sequence.fa
/mnt/datagenetique/ANALYSIS/Infectiologie/COVID-WGS/Analyse/RUN111_*/dragen-covidseq/2071405093_*_ds*/consensus/*.consensus_hard_masked_sequence.fa
/mnt/datagenetique/ANALYSIS/Infectiologie/COVID-WGS/Analyse/RUN111_*/dragen-covidseq/2071405134_*_ds*/consensus/*.consensus_hard_masked_sequence.fa
现在,我想将不同文件的所有内容连接到一个文件中。我尝试了以下简单的管道命令:
awk -F, 'NR>0 {print "/mnt/datagenetique/ANALYSIS/Infectiologie/COVID-WGS/Analyse/" $2 "_*/dragen-covidseq/" $1 "_*_ds*/consensus/*.consensus_hard_masked_sequence.fa"}' input.csv | xargs cat > output.fasta
但是我有“没有这样的文件或目录”错误,因为xargs
似乎将*
解释为一个字符,而不是通配符。关于信息,除了*
,我没有空间或任何空间字符在我的道路上。
你知道怎么做吗?
发布于 2022-01-19 15:57:20
如果要将*
字符展开为shell glob字符(通配符),则必须将它们传递给执行此操作的程序,例如shell。
假设输入文件的字段不包含对shell具有特殊意义的其他字符,则可以尝试(1):
awk -F, 'NR>0 {print "cat /mnt/datagenetique/ANALYSIS/Infectiologie/COVID-WGS/Analyse/" $2 "_*/dragen-covidseq/" $1 "_*_ds*/consensus/*.consensus_hard_masked_sequence.fa"}' input.csv | sh > output.fasta
awk
命令打印像cat /path/with/wildcards/to/some/file
这样的命令,这些命令通过管道传输到shell以进行解释。如果要避免对每个文件运行单独的cat
进程,可以让shell打印文件名并将其传递给xargs
(2):
awk -F, 'NR>0 {print "echo /mnt/datagenetique/ANALYSIS/Infectiologie/COVID-WGS/Analyse/" $2 "_*/dragen-covidseq/" $1 "_*_ds*/consensus/*.consensus_hard_masked_sequence.fa"}' input.csv | sh | xargs cat > output.fasta
当我使用问题中所示的输入文件从(1)运行awk
命令时,awk
命令的输出是
cat /mnt/datagenetique/ANALYSIS/Infectiologie/COVID-WGS/Analyse/RUN111_*/dragen-covidseq/2071404446_*_ds*/consensus/*.consensus_hard_masked_sequence.fa
cat /mnt/datagenetique/ANALYSIS/Infectiologie/COVID-WGS/Analyse/RUN111_*/dragen-covidseq/2071405093_*_ds*/consensus/*.consensus_hard_masked_sequence.fa
cat /mnt/datagenetique/ANALYSIS/Infectiologie/COVID-WGS/Analyse/RUN111_*/dragen-covidseq/2071405134_*_ds*/consensus/*.consensus_hard_masked_sequence.fa
注意,输出行以cat
开头(与问题中的awk
命令相反)。
我无法通过shell测试*
字符的扩展,因为我没有任何与模式匹配的文件。
来自(2)的awk
命令将创建类似的输出,但使用的是echo
而不是cat
。
发布于 2022-01-19 18:36:58
只要$base
和$fa_pattern
中没有特殊的shell字符,它就可以工作:
base=/mnt/datagenetique/ANALYSIS/Infectiologie/COVID-WGS/Analyse/
fa_pattern=_*_ds*/consensus/*.consensus_hard_masked_sequence.fa
# Generate one file per pattern
cat input.csv |
parallel --colsep , eval cat $base/{2}_*/dragen-covidseq/{1}$fa_pattern '>' {1}.fa
# Put everything in a single file
cat input.csv |
parallel --colsep , eval cat $base/{2}_*/dragen-covidseq/{1}$fa_pattern > all.fa
# This may be faster
cat input.csv |
parallel --colsep , -uj1 eval cat $base/{2}_*/dragen-covidseq/{1}$fa_pattern > all2.fa
发布于 2022-01-19 23:07:16
当然,让shell自己来解释输入数据,但这正是您所需要的帮助:
$ echo first > foolbar
$ echo second > foo\*bar
$ cat $(awk 'BEGIN{print "foo*bar"}')
second
first
以上假设cat
的参数列表不会超过shell的最大args长度,请参见https://stackoverflow.com/a/4185165/1745001。另一种选择是:
$ while IFS= read -r file; do cat $file; done < <(awk 'BEGIN{print "foo*bar"}')
second
first
https://unix.stackexchange.com/questions/687031
复制相似问题