我有一个命令可以获取 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
解释*
为字符而不是通配符。作为信息,除了 之外 *
,我的路径中没有空间或任何空间字符。
你知道该怎么做吗?
答案1
如果您想将这些*
字符扩展为 shell 全局字符(通配符),您必须将它们传递给执行此操作的程序,例如 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
当我awk
使用问题中所示的输入文件从 (1) 运行命令时,命令的输出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
。
答案2
只要其中没有特殊的 shell 字符$base
,$fa_pattern
这应该可以工作:
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
答案3
当然,让 shell 解释输入数据的风险由您自己承担,但这就是您需要帮助的原因:
$ echo first > foolbar
$ echo second > foo\*bar
$ cat $(awk 'BEGIN{print "foo*bar"}')
second
first
上面假设参数列表为cat
不会超过 shell 最大参数长度,请参阅https://stackoverflow.com/a/4185165/1745001。或者:
$ while IFS= read -r file; do cat $file; done < <(awk 'BEGIN{print "foo*bar"}')
second
first