문자열 입력 파일을 읽고, 일치를 수행하고, 일치 항목을 변경하려면 어떻게 해야 합니까?

문자열 입력 파일을 읽고, 일치를 수행하고, 일치 항목을 변경하려면 어떻게 해야 합니까?

문자열/파일 이름이 별도의 줄에 있는 텍스트 파일이 있습니다. 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.txtresults.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()선행을 + 접두사로 바꾸고 >이를 >(지시문을 통해) 변수로 전달합니다.awkprefix-v
  • "stray"는 가능한 모든 수정 사항을 포함하여 현재 줄을 인쇄하도록 1지시하는 것처럼 보입니다(그러나 첫 번째 파일을 처리하는 동안 해당 섹션에 도달하지 못한 경우에만 해당).awkresults.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

관련 정보