문자열/파일 이름이 별도의 줄에 있는 텍스트 파일이 있습니다. 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
- "stray"는 가능한 모든 수정 사항을 포함하여 현재 줄을 인쇄하도록
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