Bash의 값을 기반으로 두 파일의 줄을 연결합니다.

Bash의 값을 기반으로 두 파일의 줄을 연결합니다.

Bash 스크립트를 사용하여 2개의 파일을 결합하려고 하는데 다음과 같습니다.

파일 1:

John (20)
Jim (30)
Adrian Lors (23)

파일 2:

Jim
some jim info here
some jim other info
more jim info

John
some john info here
some john other info
more john info

Adrian Lors
some adrian info here
some adrian other info
more adrian info

예상되는 결과는 다음과 유사할 것으로 예상하지만 시도할 수는 없습니다.

파일 3:

Jim (30)
some jim info here
some jim other info
more jim info

Adrian Lors (23)
some adrian info here
some adrian other info
more adrian info

John (20) 

some john info here
some john other info
more john info

이상적으로는 file3을 괄호 안의 숫자로 정렬하고 싶지만 가장 큰 문제는 두 파일을 결합할 수 없다는 것입니다. 쉘 스크립트에서 이를 어떻게 달성할 수 있습니까?

감사해요

답변1

이것이 당신이 찾고 있는 것일 수도 있습니다:

$ cat tst.awk
NR==FNR {
    val = $NF
    gsub(/^[[:space:]]+|[[:space:]]+[^[:space:]]+[[:space:]]*$/,"")
    map[$0] = val;
    next
}
FNR==1 {
    FS = OFS = "\n"
    ORS = "\n\n"
    $0 = $0
}
{
    $1 = $1 " " map[$1]
    print
}

$ awk -f tst.awk file1 RS= file2
Jim (30)
some jim info here
some jim other info
more jim info

John (20)
some john info here
some john other info
more john info

Adrian Lors (23)
some adrian info here
some adrian other info
more adrian info

답변2

join, GNU sed및 다음을 사용하십시오 sort.

join -t '#'\
  <(sed 's/ (/#(/' file1 | sort)\
  <(sed -z 's/\n/#/g; s/##/\n/g; $ s/#$//' file2 | sort)\
  | sort -t'#' -nrk2.2\
  | sed '2,$ s/^/\n/g; s/#/ /; s/#/\n/g'

이 명령에서는 사용되지 않는 문자가 #임시 필드 구분 기호 및 줄 바꿈으로 사용됩니다.

산출:

Jim (30)
some jim info here
some jim other info
more jim info

Adrian Lors (23)
some adrian info here
some adrian other info
more adrian info

John (20)
some john info here
some john other info
more john info

상세한

첫 번째 매개변수join

$ sed 's/ (/#(/' file1 | sort
Adrian Lors#(23)
Jim#(30)
John#(20)

각 줄의 마지막 공백 문자를 조인 구분 기호로 바꾸고 #결과를 정렬합니다.


두 번째 매개변수 join:

$ sed -z 's/\n/#/g; s/##/\n/g; $ s/#$//' file2 | sort
Adrian Lors#some adrian info here#some adrian other info#more adrian info
Jim#some jim info here#some jim other info#more jim info
John#some john info here#some john other info#more john info
  • sed -z개행을 쉽게 대체하기 위해 파일을 읽는 데 사용됩니다 .
  • 처음 두 개의 대체 문자는 각 이름의 텍스트를 한 줄에 배치하는 데 사용됩니다. 각 개행 문자를 one 으로 바꾸고 #, ##뒤의 두 개를 하나의 개행 문자로 바꿉니다.
  • 마지막 대체 문자 #는 파일 끝에서 제거됩니다(마지막 개행 문자).
  • 결과를 정렬합니다.

연결하고 다시 정렬한 결과는 다음과 같습니다.

$ join -t '#'\
    <(sed 's/ (/#(/' file1 | sort)\
    <(sed -z 's/\n/#/g; s/##/\n/g; $ s/#$//' file2 | sort)\
    | sort -t'#' -nrk2.2
Jim#(30)#some jim info here#some jim other info#more jim info
Adrian Lors#(23)#some adrian info here#some adrian other info#more adrian info
John#(20)#some john info here#some john other info#more john info

첫 번째 필드에서 두 개의 절차적 대체를 연결하고 두 번째 필드를 위치 2부터 시작하여 역순으로 숫자로 정렬합니다.


남은 부분

... | sed '2,$ s/^/\n/g; s/#/ /; s/#/\n/g'

조인 구분 기호를 바꾸고 개행 문자를 다시 가져옵니다.

  • 라인 2(빈 라인)로 시작하는 각 라인의 시작 부분에 개행 문자를 추가합니다.
  • 각 줄의 첫 번째 줄을 #공백 문자로 바꾸고 나머지 #'를 개행 문자로 바꿉니다.

답변3

작동하다:

이상적으로는 file3을 괄호 안의 숫자로 정렬하고 싶습니다.

노력하다

$ sort -t\( -k2 file1 | awk '
FNR == NR       {X = $1;
                 sub ($1 FS, "")
                 T[X] = $0
                 next
                }
                {X = $0
                 sub (/ [^ ]*$/, "", X)
                }
X in T          {print $0, T[X] 
                }
' RS= FS="\n" file2 RS="\n" ORS="\n\n" OFS="\n" -
John (20)
some john info here
some john other info
more john info

Adrian Lors (23)
some adrian info here
some adrian other info
more adrian info

Jim (30)
some jim info here
some jim other info
more jim info

sort필요에 따라 "괄호 안의 숫자"로 file1을 정렬한 다음 file2를 읽고 레코드 구분 기호로 빈 줄을 사용하여 $1로 인덱스된 배열에 저장한 다음 file1의 정렬된 결과를 사용하여 인덱스별로 배열을 인쇄합니다.

관련 정보