별도의 줄에 문자열/파일 이름이 포함된 텍스트 파일이 있습니다. filename.txt
. 수백 개의 파일 이름이 있습니다
ABC123_S386_R1_001
JKL345_S441_R1_001
filename9000_S587_R1_001
문자열/파일 이름과 추가 데이터가 포함된 또 다른 텍스트 파일입니다. results.txt
:
>ABC123_S386_R1_001
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
>JKL345_S441_R1_001
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
>abc7890_S387_R1_001
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
>filename9000_S587_R1_001
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
이제 의 모든 파일 이름이 filename.txt
에 존재하지 않으며 results.txt
순서대로 표시되지도 않습니다. filename.txt
의 모든 파일 이름에는 접두사를 삽입하고 다른 파일 이름에는 삽입하고 싶지 results.txt
않습니다.
문자열 입력 파일을 읽고, 다른 파일과 일치시키고, 일치 항목을 변경하려면 어떻게 해야 합니까?
이전에는 개별 파일 이름을 와 일치시키고 sequence.txt
줄 번호를 얻은 다음 sed
줄 번호와 함께 사용하여 한 줄이나 줄 블록을 변경했습니다.
내가 원하는 출력은 다음과 같습니다
>h-19/US/CA-ABC123_S386_R1_001
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
>h-19/US/CA-JKL345_S441_R1_001
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
>abc7890_S387_R1_001
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
>h-19/US/CA-filename9000_S587_R1_001
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
h-19/US/CA-
모든 일치 항목에 추가하고 싶은 접미사는 어디에 있습니까?
편집: >
변경해야 하는 모든 문자열의 첫 번째 문자입니다. >
파일 이름 뒤에 오는 공백도 앞에 문자가 없습니다.
답변1
의 관련 줄에 results.txt
파일 이름 뒤에 공백이 포함되어 있지 않다고 가정하면 다음 awk
프로그램이 작동합니다.
awk -v prefix="h-19/US/CA-" 'NR==FNR{fnames[$1]; next} \
/^>/{name=substr($0,2); if (name in fnames) {sub(/^>/, ">" prefix)} }1' filenames.txt results.txt
- 먼저 구문 분석
filenames.txt
한 다음results.txt
. - 구문 분석하는 동안
filenames.txt
(FNR
파일별 라인 카운터는NR
전역 라인 카운터와 동일함) 모든 파일 이름(라인의 유일한 필드)을 배열에 등록fnames
하지만 실행을 즉시 다음 라인으로 건너뜁니다. - 구문 분석하는 동안
results.txt
줄이 로 시작하는지 확인합니다>
. 그렇다면 해당 문자 뒤의 하위 문자열( 임시로 저장됨name
)이 의 "배열 인덱스"에서 발견되는지 확인합니다fnames
. 이 경우sub()
선행을 +접두사>
로 대체하고 (지시문을 통해 ) 변수로 전달하는 데 사용됩니다 .>
awk
prefix
-v
- 겉으로 보기에는 "길어"인 것처럼 보이는 것은 가능한 모든 수정 사항을 포함하여 현재 줄을 인쇄하도록
1
지시합니다 (그러나 첫 번째 파일을 처리하는 동안 해당 부분에 도달하지 못하는 경우에만 해당됩니다).awk
results.txt
그 자체로 는 awk
파일을 내부에서 수정할 수 없으므로 임시 파일을 사용하여 작업해야 합니다. 그러나 충분히 새로운 버전의 GNU Awk(> 4.1.0)가 있는 경우 inplace
확장 기능을 사용할 수 있습니다. 물론 그런 다음 해당 파일에 대한 옵션을 꺼야 합니다 filenames.txt
.
awk -i inplace -v prefix=" ... " ' ... ' inplace=0 filenames.txt inplace=1 results.txt
그러면 에 대한 내부 편집이 꺼졌다 filenames.txt
가 다시 켜집니다 results.txt
.
답변2
sed
보류 공간에서 파일 이름을 수집한 다음 일치 항목을 확인하는 모든 줄에 대해 변경할 results.txt
줄을 필터링할 수 있습니다.
sed -e '1,/^$/{H;1h;d;}' -e 'G;/^>\(.*\).*\n\1\n/s_^>_>h-19/US/CA-_;P;d' filename.txt <((echo)) results.txt
<((echo))
파일 사이 에 빈 줄을 전달하여1,/^$/
첫 번째 파일의 모든 줄(및 빈 줄)을 처리합니다.- 해당 줄은 공간을 유지하기 위해 추가된 다음 삭제됩니다
H;1h;d
(1h
개행으로 보류 공간을 시작하지 않음). G
의 모든 라인에 보류 공간을 추가하고result.txt
파일 이름인 문자열/^>\(.*\).*\n\1\n/
로 시작하는 라인과 일치합니다 (보류 공간에서 개행 문자로 묶음).>
s_^>_>h-19/US/CA-_
해당 라인을 교체합니까?P;d
추가된 정크 없이 첫 번째 줄만 인쇄합니다.s/\n.*//
대신 할 수 있습니다
답변3
perl
입력 파일에 대한 내부 편집에 사용 :
pfx='h-19/US/CA-' \
perl -pi -e '
BEGIN { %h = map { tr/\n//dr => $ENV{pfx}} <STDIN>}
s/^>\K(?=(.*))/$h{$1}/;
' results.txt < filename.txt