csv 파일의 두 열을 비교하고 일치하지 않는 레코드만 표시

csv 파일의 두 열을 비교하고 일치하지 않는 레코드만 표시

다음 형식의 csv 파일이 있습니다.

1311,0008,a131,a131,7039
1311,0008,a131,a132,7039
1711,2046,a626565,a626566,7099
1711,2048,a626565,a626565,7035

내가 원하는 것은 열 3과 4만 비교하고, 일치하지 않으면 새 파일에 해당 줄을 인쇄하고, 일치하면 해당 줄을 다른 파일에 인쇄하는 것입니다.

예상되는 File1 출력(열 3과 4가 일치하지 않음):

1311,0008,a131,a132,7039
1711,2046,a626565,a626566,7099

File2의 예상 출력(열 3과 4가 일치함):

1311,0008,a131,a131,7039
1711,2048,a626565,a626565,7035

지금까지는 여러 파일을 비교해 보았습니다.

답변1

awk -F, '{ print >($3==$4?"matchedFile":"notMatchedFile") }' infile

열#3이 동일한 경우 선택적으로 두 출력 파일 중 하나로 행을 리디렉션합니다.전체 문자열 일치열#4( 쉼표로 구분된 열, 로 지정됨 -F,)를 사용하여 다음을 작성합니다.matchedFile출력 파일, 그렇지 않으면 쓰기notMatchedFile.

바라보다다른 매칭 옵션은 여기.


$ head matchedFile notMatchedFile
==> matchedFile <==
1311,0008,a131,a131,7039
1711,2048,a626565,a626565,7035

==> notMatchedFile <==
1311,0008,a131,a132,7039
1711,2046,a626565,a626566,7099

또는 비슷하지만 명령을 더 간결하게 만듭니다.

awk -F, '{ print >"file"($3==$4) }' infile

$ head file[01]
==> file0 <==
1311,0008,a131,a132,7039
1711,2046,a626565,a626566,7099

==> file1 <==
1311,0008,a131,a131,7039
1711,2048,a626565,a626565,7035

답변2

간단하게 유지하기 위한 매우 짧은 명령 두 개:

awk -F, '$3 != $4' file.csv >file1
awk -F, '$3 == $4' file.csv >file2

두 명령 모두 in 의 행을 file.csv쉼표로 구분된 필드 집합으로 처리합니다. 세 번째 필드가 네 번째 필드와 같지 않을 때마다 첫 번째 명령은 현재 행을 씁니다(그리고 file1출력 리디렉션을 통해 씁니다). 두 번째 명령은 동일한 작업을 수행하지만 반대 논리를 사용합니다(그리고 출력은 다음과 같습니다 file2).

단일 명령을 사용하는 것은 약간 더 복잡하지만 파일 설명자 3과 4를 간단히 리디렉션하여 명령줄에서 출력 파일의 이름을 지정할 수 있습니다.

$ awk -F, '{ fd = $3 == $4 ? 4 : 3;  print >("/dev/fd/" fd) }' file.csv 3>file1 4>file2
$ cat file1
1311,0008,a131,a132,7039
1711,2046,a626565,a626566,7099
$ cat file2
1311,0008,a131,a131,7039
1711,2048,a626565,a626565,7035

아니면 똑같지만 더 혼란스럽습니다.

awk -F, '{ print >("/dev/fd/" 3 + ($3 == $4)) }' file.csv 3>file1 4>file2

답변3

GNU sed 방법:

F="[^,]*,"
sed -En "
  /^($F){2}($F)\\2/w match.csv"'
  //!w nomatch.csv
' file.csv

결과는 현재 디렉터리의 match/nomatch .CSV 파일에 저장됩니다.

관련 정보