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

이제 서로 다른 파일의 모든 내용을 하나의 파일로 연결하고 싶습니다. 다음과 같은 간단한 파이프 명령을 시도했습니다.

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

출력 라인은 다음으로 시작됩니다.cat( awk질문의 명령과 반대).

*패턴과 일치하는 파일이 없기 때문에 쉘의 문자 확장을 테스트할 수 없습니다 .

(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

관련 정보