두 파일을 비교하고 일치 기준에 따라 다른 파일을 생성합니다.

두 파일을 비교하고 일치 기준에 따라 다른 파일을 생성합니다.

a.txt와 b.txt라는 두 개의 파일이 있습니다. 여기서 a.txt에는 zn12c5b 또는 zn4i8l과 같이 "zn"으로 시작하는 줄이 포함되어 있고 b.txt에는 t17v11/과 같이 "/number" 패턴으로 끝나는 줄이 포함되어 있습니다. 112 또는 12c5b/450.

내 목표는 b.txt의 문자열(후행 "/number" 패턴 없음)과 일치하지 않는 a.txt의 문자열("zn" 없음)을 Final.txt에 작성하는 것입니다.

예를 들어:

a.txt:

zn12c5b
zn4i8l

b.txt:

t17v11/112
12c5b/450
4i8ls/681

Final.txt에서 다음과 같은 출력을 얻어야 합니다.

4i8l

참고: a.txt 파일의 4i8l("zn" 접두사 없음)은 파일의 4i8ls("/681" 접미사 없음)와 동일하지 않습니다. 저는 우분투 시스템을 사용하고 있습니다.

답변1

$ awk -F'/' 'NR==FNR{b[$1]; next} {sub(/^zn/,"")} !($1 in b)' b.txt a.txt
4i8l

답변2

다음 bash 스크립트가 작업을 수행해야 합니다(bash 4 이상으로 시작).

#!/bin/bash
readarray -t a_arr < a.txt
readarray -t b_arr < b.txt

for a_el in "${a_arr[@]}"
do 
    # remove the first two characters 'zn'
    substr_a=${a_el:2}
    isin=0
    for b_el in "${b_arr[@]}"
    do  
        # extract matches from b.txt file
        substr_b=$(echo $b_el | sed -n "s#^\(.*\)\/[[:digit:]]\+#\1#p")
        if [ "$substr_a" == "$substr_b" ];then isin=1; break;fi
    done
    if [ $isin -eq 0 ];then echo $substr_a ;fi
done > final.txt

4보다 낮은 bash 버전을 사용하는 경우 readarray이 줄을 다음으로 바꿔야 합니다.

a_arr=($(<a.txt))
b_arr=($(<b.txt))

답변3

못생긴 네티즌들은 이렇게

sdiff -s <(sed 's/^zn//' a.txt|sort) <(awk -F/ '{ print $1 }' b.txt| sort) | awk -F'[<|>]' '{ print $1 }'
#1         #2                          #3                                    #4 

일을 할 것입니다.

설명하다:

#1 sdiff2개의 텍스트 파일을 한 줄씩 비교합니다. -s 옵션은 공통 줄을 억제합니다.

#2 seda.txt 파일의 각 줄 시작 부분에서 zn 접두사를 제거합니다.

awk#3은 b.txt 파일의 각 줄의 왼쪽 부분 만 출력하라는 지시를 받았습니다./

< |#4 또 다른 awk는 문자열이나 문자의 왼쪽 부분만 출력하라는 지시를 받습니다 >. 이러한 문자는 sdiff출력의 구분 기호입니다.

<(somecommand) 관용구라고도 함프로세스 교체일부 명령의 출력으로 생성된 콘텐츠가 포함된 파일 이름으로 처리됩니다.

| sort분명히 출력은 sdiff정렬된 파일을 제공하기 위해 정렬됩니다.

답변4

awkGNU (구현됨 BEGINFILE) 가 있는 경우 다음을 수행할 수 있습니다.

awk 'BEGINFILE{FS=(NR!=0)?"^..":"/"}
     NR==FNR{test[$1]=1; next}
     !($2 in test){print $2}' b.txt a.txt

418l

a.txt새 파일로 리디렉션하는 대신 다시 쓰려면 다음 > final.txt을 추가할 수 있습니다.

| sponge a.txt

송곳

awk 'BEGINFILE{FS=(NR!=0)?"^..":"/"}

첫 번째 파일이 열릴 때 BEGINFILE실행 NR==0되므로FS=/

     NR==FNR{test[$1]=1; next}

테스트 배열에 NR==FNR로드된 첫 번째 파일을 반복합니다.$1

두 번째 파일이 열리면 다시 실행되지만 BEGINFILE이제 입력 줄의 처음 두 문자 이후의 모든 내용을 NR!=0제거합니다 .FS=^..$2

     !($2 in test){print $2}' b.txt a.txt

print $2테스트 배열에 없는 경우 두 번째 파일을 반복합니다 !($2 in test).

관련 정보