두 파일을 한 줄씩 비교해야 합니다. 나는 다른 줄만 출력하고 싶지만 차이점을 판단할 때 문자 4-6과 10-12는 무시해야 합니다. 특정 필드 구분 기호 등이 없습니다.
예:
- 파일 1
abc123def999 ghi456klm999 nop789qrs999
- 파일 2
abc000def000 xxx000yyy000 nop000qrs000
이 예에서는 두 번째 행만 달라야 합니다.
read
파일에 수백만 개의 레코드가 있기 때문에 루프가 파일을 한 줄씩 구문 분석하는 것을 원하지 않습니다 .
답변1
GNU awk를 FIELDWIDTHS 매개변수로 사용:
$ paste file[12] |
awk -v FIELDWIDTHS='3 3 3 3 1 3 3 3 3' '$1!=$6 || $3!=$8'
ghi456klm999 xxx000yyy000
paste
여기서는 두 파일을 나란히 붙여넣는 명령을 사용합니다 . 그런 다음 awk의 FIELDWIDTHS 매개변수를 사용하여 필드 길이를 정의하므로 두 파일의 행이 고정 길이라고 가정하고 여기에서 관련 필드의 차이점을 비교합니다. 한 줄씩 수행됩니다.
또는 모든 쉘에서 awk를 사용하십시오.
$ paste file[12] |
awk 'function key(s){return substr(s,1,3) substr(s,7,3)} key($1) != key($2)'
ghi456klm999 xxx000yyy000
답변2
예상되는 출력을 표시하지 않았고 요구 사항이 무엇인지 실제로 알려주지 않았으므로 다음은 모든 Unix 시스템의 모든 쉘에서 awk를 사용하여 원하는 것이 무엇인지 추측합니다.
$ cat tst.awk
{ key = substr($0,1,3) substr($0,7,3) }
NR == FNR {
a[key]
next
}
!(key in a)
$ awk -f tst.awk file1 file2
xxx000yyy000
$ awk -f tst.awk file2 file1
ghi456klm999
답변3
두 파일 모두 "수백만 개의 레코드"를 가지고 있습니까? 더 짧은 파일을 선택하고 각 줄을 읽은 다음 " ^
"(줄 시작) 으로 $
시작하고 " "(줄 끝)으로 끝나는 정규식을 생성합니다. 검색 문자열은 그 사이에 있습니다. 무시할 위치를 " .
"(정규식 "모든 단일 문자와 일치")로 설정합니다. 예를 들어" ^abc...def...$
". 임시 파일( file1.tmp
)에 저장합니다(수백만?). 모든 줄을 처리하면 in에서 grep -E -f file1.tmp file2
정규식을 검색합니다.file1.tmp
file2
답변4
방법 1)perl
이 unpack
기능은 Perl 환경 트레이에 제공된 형식을 기반으로 특정 범위의 문자를 추출하므로 이러한 상황에 가장 적합합니다. (A3x3)2A*
=> 3개의 ASCII 문자를 선택한 다음 3개의 문자를 건너뜁니다. 이 과정을 다시 반복하고 남은 것을 가져옵니다.
fmt='(A3x3)2A*' \
perl -nse 'print if "@{[unpack($ENV{fmt})]}" ne
"@{[unpack($ENV{fmt},scalar(<STDIN>))]}";
' -- -\"= File1 < File2
ghi456klm999
방법-2)paste+GNU sed
붙여넣기는 두 파일의 해당 줄을 탭으로 구분하여 나란히 배치합니다. 따라서 파일에 탭이 없어야 한다고 가정합니다. 그런 다음 두 파일의 데이터에서 4-6 및 10-12 문자를 동일한 문자 "."로 바꿉니다. 라인을 비교하기 전에 Ines가 일치하지 않으면 file1 줄을 인쇄합니다.
# helper vars aid in writing sed code
x3='...'
A3="($x3)"
A3x3=$A3$x3
srch="^$A3x3$A3x3"
repl="\\1$x3\\2$x3"
paste File1 File2 |
sed -En 'y/\t/\n/;h
'"s/$srch/$repl/Mg"'
/^(.*)\n\1$/d;g;P
' -
방법-3)Python
내장된 zip 기능은 두 파일의 줄을 나란히 봅니다.
python3 -c 'import sys
# skip chars: 4-6 10-12
AoT = [(0,3),(6,9),(12,None)] # array of tuples
fx = lambda t: \
a[t[0]:t[1]] != b[t[0]:t[1]]
ifile1,ifile2 = sys.argv[1:]
with open(ifile1) as f1,\
open(ifile2) as f2:
for a,b in zip(f1,f2):
if any(map(fx,AoT)):
print(a,end="")
' File1 File2