sed/awk/etc를 사용하여 한 텍스트 파일의 홀수 줄을 다른 텍스트 파일의 해당 홀수 줄로 바꿉니다.

sed/awk/etc를 사용하여 한 텍스트 파일의 홀수 줄을 다른 텍스트 파일의 해당 홀수 줄로 바꿉니다.

텍스트 파일의 한 줄을 다른 텍스트 파일의 해당 줄로 바꾸고 싶습니다.

파일 1의 내용:

>line1  
GGG  
>line2  
AAA  
>line3  
TTT  
>line4  
CCC  
>line5  
CAT 

파일 2의 내용:

>name.A
CTGG  
>name.B
GACC  
>name.C
CTGG  
>name.D
GGAA  
>name.E
GCTA

두 파일의 줄 수는 동일합니다. 최종 파일은 다음과 같아야 합니다.

>name.A  
GGG   
>name.B  
AAA  
>name.C  
TTT  
>name.D  
CCC  
>name.E  
CAT 

해결책을 찾았지만 찾을 수 없는 것 같습니다. 나는 다음을 시도했습니다.

awk 'FNR==NR {data[FNR]=$0; next} (FNR%2==1){$0=data[FNR]}1' < File1 < File2

그러나 아무 일도 일어나지 않았습니다.

어떤 도움이라도 대단히 감사하겠습니다!

답변1

$ awk 'NR==FNR{a[NR]=$0; next} {print (FNR%2 ? $0 : a[FNR])}' file1 file2
>name.A
GGG
>name.B
AAA
>name.C
TTT
>name.D
CCC
>name.E
CAT

더 간결하고 효율적일 뿐만 아니라 :-) 위의 접근 방식은 다음과 같은 이유로 여러분이 사용하는 접근 방식보다 더 효율적입니다.

  1. $0에 할당되지 않았으므로 awk가 레코드를 필드로 다시 분할하도록 강제하지 않습니다.
  2. 1인쇄 여부를 결정하기 전에 각 줄의 두 번째 조건( )을 테스트하지 않습니다.

또한 입력 리디렉션을 사용하여 awk 파일을 열지 마십시오. 여러 파일에서 작동하지 않으며(발견한 대로) FILENAME을 확인할 수 있는 기능이 없어집니다.

답변2

먼저 유틸리티를 호출하여 paste탭으로 구분된 방식으로 줄을 정렬한 다음 sed편집기를 호출하여 원하는 데이터 출력을 얻는 작업을 수행하여 pbm을 수행할 수 있습니다.

$ paste File1 File2  | sed -ne '
    s/>.*\t//p
    s/\t.*//p
 '

산출

>name.A
GGG  
>name.B
AAA  
>name.C
TTT  
>name.D
CCC  
>name.E
CAT 

\t참고: Posix sed는 탭 문자를 나타내는 이스케이프 시퀀스를 인식하지 못합니다 . 나는 단지 보이지 않는 문자를 강조하기 위해 그것을 사용합니다. 따라서 \t 대신 텍스트 탭 문자를 넣을 수 있습니다.

실용성을 더하면 Perl다음과 같은 문장이 됩니다.

$ perl -pe '$_=($_,$,.<STDIN>)[$.%2]' File1 < File2

답변3

awk 명령은 기본적으로 정확합니다. 불필요한 리디렉션을 제거하고 파일 순서를 바꾸면 작동합니다.

$ awk 'FNR==NR {data[FNR]=$0; next} (FNR%2==1){$0=data[FNR]}1' File2 File1
>name.A
GGG  
>name.B
AAA  
>name.C
TTT  
>name.D
CCC  
>name.E
CAT 

또는 GNU sed와 프로세스 대체를 지원하는 셸을 사용하세요.

$ sed -e '2~2{R /dev/stdin' -e 'd}' File2 < <(sed '1~2d' File1)
>name.A
GGG  
>name.B
AAA  
>name.C
TTT  
>name.D
CCC  
>name.E
CAT 

설명하다:

  • sed '1~2d' File1File1에서 홀수 행 삭제

  • < <(...)stdin을 통해 결과 입력

  • sed -e '2~2{R /dev/stdin' -e 'd}' File2stdin에서 한 번에 한 줄씩 읽고 다음 짝수 줄 다음에 File2에 삽입하도록 대기열에 넣은 다음 짝수 줄을 삭제합니다.

답변4

sed 명령을 사용해 보았는데 훌륭하게 작동합니다.

for ((i=2;i<=10;i++));do j=`sed -n ''$i'p' f1`; k=`echo $j|sed -r "s/\s+//g"`;sed -i ""$i"s/.*/"$k"/g" f2;i=$(($i+1)); done

산출

>name.A
GGG
>name.B
AAA
>name.C
TTT
>name.D
CCC
>name.E
CAT

관련 정보