한 파일의 빈 줄을 다른 파일의 줄로 바꾸기

한 파일의 빈 줄을 다른 파일의 줄로 바꾸기

나는 가지고있다파일 1.csv

"word 1"
""
"word 3"
""
"word 5"
"word 6"

그리고파일 2.csv

"replacement text 1"
"replacement text 2"
"replacement text 3"
"replacement text 4"
"replacement text 5"
"replacement text 6"

file1에 빈 줄(또는 ""가 있는 줄)이 있는지 확인한 다음 이를 file2의 내용으로 바꾸는 명령을 찾고 있습니다.

이것출력.csv~해야 한다

"word 1"
"replacement text 2"
"word 3"
"replacement text 4"
"word 5"
"word 6"

답변1

파일의 행 수가 동일하다고 가정: paste첫 번째 파일의 필드를 제목 없는 첫 번째 열로, 두 번째 파일의 필드를 제목 없는 두 번째 열로 사용하여 CSV 레코드 스트림을 만드는 데 사용됩니다.

$ paste -d , file1.csv file2.csv
"word 1","replacement text 1"
"","replacement text 2"
"word 3","replacement text 3"
"","replacement text 4"
"word 5","replacement text 5"
"word 6","replacement text 6"

그러면 우리는 사용할 수 있습니다밀러첫 번째 필드가 비어 있으면 첫 번째 필드를 두 번째 필드의 값으로 업데이트합니다.

$ paste -d , file1.csv file2.csv| mlr --csv -N put 'is_empty($1) { $1 = $2 }'
word 1,replacement text 1
replacement text 2,replacement text 2
word 3,replacement text 3
replacement text 4,replacement text 4
word 5,replacement text 5
word 6,replacement text 6

is_empty()해당 필드가 입력에서 참조되는지 여부에 관계없이 모든 빈 필드에 대해 테스트가 적용됩니다 .

그런 다음 첫 번째 필드를 잘라낼(추출) 수 있습니다.

$ paste -d , file1.csv file2.csv| mlr --csv -N put 'is_empty($1) { $1 = $2 }' then cut -f 1
word 1
replacement text 2
word 3
replacement text 4
word 5
word 6

Miller는 실제로 인용해야 하는 필드만 인용합니다. Miller가 모든 출력 필드를 인용하도록 하려면 다음을 사용하십시오 --quote-all.

$ paste -d , file1.csv file2.csv| mlr --csv -N --quote-all put 'is_empty($1) { $1 = $2 }' then cut -f 1
"word 1"
"replacement text 2"
"word 3"
"replacement text 4"
"word 5"
"word 6"

이와 같은 것을 확실히 비슷한 일을 할awk사용하면awk

$ paste -d , file1.csv file2.csv| awk -F , '$1 == "\"\"" { $1 = $2 } { print $1 }'
"word 1"
"replacement text 2"
"word 3"
"replacement text 4"
"word 5"
"word 6"

답변2

또 다른 awk옵션:

awk '{getline other < "file2.csv"}
     $0 == "\"\"" {$0 = other}
     {print}' file1.csv > output.csv

또는 paste+ sed:

paste -d '\n' file1.csv file2.csv| sed 'N;s/^""\n//;s/\n.*//' > output.csv

file2.csv만족할 행이 충분하지 않으면 모든 ""행이 1로 재사용되고 마지막 행에 + 1을 사용하면 빈 행이 생성됩니다. 그보다 더 많은 줄이 있으면 거기에 추가 빈 줄도 생깁니다.file1.csvawkfile2.csvpastesedfile2.csvfile1.csv

답변3

$ awk -F, 'NR == FNR    { a[FNR] = $1; next };
           $1 == "\"\"" { $1 = a[FNR] };
           1' file2.csv file1.csv 
"word 1"
"replacement text 2"
"word 3"
"replacement text 4"
"word 5"
"word 6"

file2.csv를 읽고 각 행의 열 1을 배열에 저장합니다.

그런 다음 file1.csv를 읽고 열 1이 큰따옴표 쌍(예: "비어 있음")인 경우 첫 번째 열을 배열의 적절한 요소( FNR또는 현재 파일의 현재 줄 번호)로 바꿉니다. 그런 다음 변경 여부에 관계없이 현재 줄을 인쇄합니다.

답변4

다음 Perl 스크립트는 원래 입력( file1.csv)이 stdin이고 대체 파일이 명령줄 인수로 전달된다고 가정합니다.

#!/usr/bin/perl
while (<STDIN>) {
  $_ = <> if /^("")?$/;
  print;
}

예를 들어, 다음 중 하나입니다.

$ cat file1.csv | perl this-script.pl file2.csv
$ <file1.csv | perl this-script.pl file2.csv
$ ./this-script.pl file2.csv <file1.csv

또는 한 줄로:

$ perl -e 'while (<STDIN>) { $_ = <> if /^("")?$/; print }' <file1.csv file2.csv

관련 정보