조건부로 file1의 줄을 file2의 해당 줄로 바꿉니다.

조건부로 file1의 줄을 file2의 해당 줄로 바꿉니다.

예를 들어 다음과 같은 두 개의 파일이 있습니다.

파일 1:

1
4
X
5
X
7

파일 2:

2
3
5
X
X
1

Xfile1의 -lines를 file2의 해당 행 내용으로 바꾸고 싶습니다 .

결과:

1
4
5
5
X
7

나는 같은 CLI 명령을 사용하는 솔루션을 선호합니다 sed.

답변1

file2가 메모리에 맞으면 awk를 사용할 수 있습니다. 먼저 file2를 읽은 다음 file1을 처리하는 동안 "X"가 표시되면 file2 배열에서 해당 파일을 바꿉니다.

$ awk 'NR == FNR { lines[NR]=$0; } NR != FNR { if ($0 == "X") print lines[FNR]; else print $0 }' file2 file1

다시 포맷하면 다음과 같습니다.

$ awk 'NR == FNR { lines[NR]=$0; } 
       NR != FNR { if ($0 == "X") print lines[FNR]; 
                   else           print $0 
                 }' file2 file1

file2는 첫 번째 파일 이름이고 file1은 두 번째 파일 이름입니다.

답변2

$ paste file1 file2 | awk -F '\t' '$1 == "X" { $1 = $2 } { print $1 }'
1
4
5
5
X
7

paste명령은 탭으로 구분된 출력을 생성합니다.

1       2
4       3
X       5
5       X
X       X
7       1

첫 번째 필드가 문자인 경우 awk스크립트는 탭으로 구분된 첫 번째 필드를 두 번째 필드의 콘텐츠로 설정한 X다음 첫 번째(현재 수정되었을 수 있음) 필드를 인쇄합니다.

다양한 방법글렌 잭맨이 추천하는 작품전달된 데이터를 수정하지 않고 첫 번째 열의 데이터를 기반으로 인쇄할 필드를 선택합니다.

$ paste file1 file2 | awk -F '\t' '{ print $1 == "X" ? $2 : $1 }'

GNU 사용 sed:

$ paste file1 file2 | sed -E -e '/^X/s/^[^\t]+\t//' -e 's/\t.*$//'
1
4
5
5
X
7

이 두 sed표현식은 다음을 수행합니다.

  1. 현재 줄이 로 시작하는 경우 X첫 번째 교체는 첫 번째 탭을 포함하여 모든 항목을 제거합니다. paste이렇게 하면 첫 번째 열이 인 경우 출력의 두 번째 열이 첫 번째 열로 효과적으로 이동됩니다 X.
  2. 두 번째 표현식은 탭 문자와 그 뒤에 오는 모든 항목을 제거합니다. 이렇게 하면 관심이 없는 데이터가 제거됩니다.

답변3

배쉬와 함께

while IFS= read -r -u3 f1; IFS= read -r -u4 f2; do
    [[ $f1 == X ]] && echo "$f2" || echo "$f1"
done 3<file1 4<file2

또는 더 일반적으로 POSIX

while IFS= read -r f1 <&3; IFS= read -f f2 <&4; do
    [ "$f1" = X ] && echo "$f2" || echo "$f1"
done 3<file1 4<file2

관련 정보