제목과 구조가 동일한 두 개의 파일이 있는데 첫 번째 열이 키입니다.
파일 1:
key val1 val2 val3 val4 val5
Item1 10 12 44 88 22
Item2 33 33 43 77 22
Item3 28 44 55 22 11
Item4 12 55 55 14 44
파일 2:
key val1 val2 val3 val4 val5
Item1 10 11 44 99 22
Item2 33 33 43 77 22
Item3 28 44 55 22 11
Item4 12 55 55 14 00
위 파일에서 알 수 있듯이 두 파일은 두 가지 측면에서 다릅니다.
- item1의 val2와 val4가 다릅니다.
- 항목 4의 val5가 다릅니다.
그래서 어떤 항목의 어떤 필드가 다른지 알려주는 비교 출력을 생성하고 싶습니다. 출력은 다음과 유사해야 합니다.
Item1: val2,val4
Item4: val5
답변1
awk -v ref=file1 '
{
getline refline <ref
if (NR == 1) split(refline, head)
nf = split(refline, a)
for (i = 1; i <= nf; ++i)
if ($i != a[i])
diffcol[++n] = i
if (n > 0) {
$0 = a[1]
for (i = 1; i <= n; ++i)
$(i+1) = head[diffcol[i]]
print
n = 0
}
}' file2
그러면 파일이 file2
'참조 파일'과 비교됩니다 file1
. from 의 행 file2
은 일반적으로 에 의해 읽혀지는 반면 from 의 행은 awk
코드에서 호출 및 분할을 통해 file1
명시적으로 읽혀집니다 .getline
awk
split
이 split(refline, head)
블록은 배열을 head
헤더로 설정하고 에서 읽습니다 file1
. 이는 의 입력 첫 번째 줄에서만 수행됩니다 file2
.
첫 번째 루프는 두 파일 간의 필드와 diffcol
다르며 배열에 추가된 필드의 열 번호를 비교합니다.
하나 이상의 차이점이 발견되면 첫 번째 필드가 출력되고 그 뒤에 file1
다른 필드(from)의 헤더가 출력됩니다.file1
코드를 작성한 방식, 헤더 행 및 첫 번째 필드도 비교 대상이므로 첫 번째 필드에서 차이점이 발견되면 아마도 key
해당 행의 시작 부분에 출력 라인도 표시됩니다. 첫 번째 필드 값 file1
).
코드에서는 두 파일의 열 수가 동일하다고 가정하지 않습니다.
질문의 데이터가 주어지면 이 코드에서 다음과 같은 출력을 얻을 수 있습니다.
Item1 val2 val4
Item4 val5
답변2
paste
awk
모든 레코드에 동일한 수의 필드가 있다고 가정하고 및 의 조합을 사용하십시오 .
paste file1 file2 |
awk -F'\t' '
NR == 1 {cols = split($0, hdr) / 2; next}
{
diff = sep = ""
for (i = 2; i <= cols; i++)
if ($i "" != $(i+cols) "") {
diff = diff sep hdr[i]
sep = ","
}
if (sep) print $1": "diff
}'
비교가 항상 어휘적( like or , from , 1e500 등)이 되도록 ""
비교의 각 측면에 추가합니다 . 필드가 숫자처럼 보이는 경우 해당 필드를 제거하여 숫자로 비교할 수 있습니다.!=
0
00
-0
inf
infinity