xargsまたはパラレルを使用してパスで*を使用して複数のファイルをリンクする方法

xargsまたはパラレルを使用してパスで*を使用して複数のファイルをリンクする方法

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

では、異なるファイルのすべてのコンテンツを1つのファイルにリンクしたいと思います。次の単純なパイプコマンドを試しました。

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

これらの文字をシェルグローバル文字(ワイルドカード)に拡張するには、*それを実行するプログラム(シェルなど)にその文字を渡す必要があります。

入力ファイルのフィールドにシェルに特別な意味を持つ他の文字が含まれていないと仮定すると、(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ない場合は、catシェルからファイル名を印刷して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

出力ラインは次から始まります。catawk質問の命令とは反対)。

*パターンに一致するファイルがないため、シェルの文字拡張をテストできません。

(2)のコマンドはawk同様の出力を生成しechoますがcat

答え2

特殊なシェル文字がない場合は、次のように$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

もちろん、シェルに入力データを解釈させる責任はユーザー自身にあります。しかし、助けが必要な理由は次のとおりです。

$ echo first > foolbar
$ echo second > foo\*bar

$ cat $(awk 'BEGIN{print "foo*bar"}')
second
first

上記は、パラメータリストがcatシェルの最大パラメータ長を超えないことを前提としています。https://stackoverflow.com/a/4185165/1745001。または:

$ while IFS= read -r file; do cat $file; done < <(awk 'BEGIN{print "foo*bar"}')
second
first

関連情報