다음 명령을 사용하여 의 일부 ID를 일치시키고 file 1
에 저장된 데이터를 검색합니다 referencefile
.
while read -r line; do
awk -v pattern=$line -v RS=">" '$0 ~ pattern { printf(">%s", $0); }' referencefile;
done <file1 >output
디렉터리에 file1과 유사한 50개의 파일이 저장되어 있고 이 모든 파일에 대해 위 명령을 실행하고 출력을 별도의 파일로 저장하려고 합니다. 하나의 명령(예: 중첩 루프)을 통해 이를 달성할 수 있는 방법이 있습니까?
참조 문서
>LD200FFFFFFFFFFFFFFFFFFFFSSSSSSSSS
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
SSSSSSSSSSSSSSS
>LD400HHHHHHHHHHHHHHHHHHHHHHHHHHHHH
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
>LD311DDDDDDDDDDDDDDDDDDDDDDDDDDDDD
>LD500TTTTTTTTTTTTTTTTTTTTTTTTTTTTT
>LD100KKKKKKKKKKKKKKKKKKKKKKKKKKKKK
샘플 파일 1
LD100
LD200
LD311
예상 출력 1.txt
>LD100KKKKKKKKKKKKKKKKKKKKKKKKKKKKK
>LD200FFFFFFFFFFFFFFFFFFFFSSSSSSSSS
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
SSSSSSSSSSSSSSS
>LD311DDDDDDDDDDDDDDDDDDDDDDDDDDDDD
샘플 파일 2
LD500
LD400
예상 출력 2.txt
>LD500TTTTTTTTTTTTTTTTTTTTTTTTTTTTT
>LD400HHHHHHHHHHHHHHHHHHHHHHHHHHHHH
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
답변1
단일 명령줄을 검색하는 대신 이를 수행하기 위해 스크립트를 사용하고 있다는 것을 이해합니다. 그렇다면 스크립트를 다음과 같이 변경하는 것은 어떻습니까?
#!/bin/bash
Directory="$1"
ls "$Directory" | while read FileName
do
while read -r line
do
awk -v pattern="$line" -v RS=">" '$0 ~ pattern { printf(">%s", $0); }' referencefile;
done < "$Directory"/"$FileName" > OutputDirectory/"$FileName".out
done
스크립트는 다음과 같이 호출되어야 합니다.
<script> <directory with input files>
사용에 관한 몇 가지 참고사항:
- 반드시 존재 해야 합니다
OutputDirectory
. 스크립트에서 편집하거나 매개변수를 추가하세요. - 입력 파일만 포함 되어야 하며
<directory with input files>
하위 디렉터리는 포함되어서는 안 됩니다. 그렇지 않으면 오류 메시지가 표시됩니다.
경고하다
스크립트는 구문 분석에 의존합니다 ls
. 이렇게 하면 방법을 더 쉽게 이해할 수 있을 만큼 스크립트를 단순하게 유지할 수 있지만 일반적으로권장되지 않음파일 이름의 특수 문자로 인해 바람직하지 않은 동작이 발생할 수 있기 때문입니다. 입력 파일의 이름이 너무 화려하지 않은 간단한 설정에서 작동합니다. 이름에 공백을 넣어도 괜찮지만, 예를 들어 이름에 줄바꿈을 사용하면 오류가 발생하고 해당 파일은 처리되지 않습니다.
답변2
일반적으로 다음과 같이 할 수 있습니다.
for f in file*; do
while read ...; do
some commands...
done < "$f"
done > output
그렇지 않으면
cat file* | while read ...; do
some commands...
done > output
네가 원한다면오직일치하는 줄이 있으면 파일에서 패턴을 읽고 일치하는 줄을 인쇄하여 grep
이 작업을 더 직접적으로 수행할 수 있습니다 .grep -f
for patternfile in file*; do
grep -f "$patternfile" referencefile
done
답변3
for 루프에서 xargs + grep에 대한 호출을 래핑할 수 있습니다. grep은 참조 파일에 표시된 순서대로 캡처하므로 출력 순서가 file1의 입력과 일치하지 않을 수 있습니다.
for f in file*;do
< "$f" paste -sd\||\
xargs -r -I{} grep -Pzo '(?m:(?:^[>](?:'{}')\D.*\n)(?:[^>].*\n)*)' reference.file | tr -d '\0' \
> "$f.out"
done