열 9-14의 문자가 다른 파일에서 발견되지 않으면 출력 파일에서 행을 제외합니다.

열 9-14의 문자가 다른 파일에서 발견되지 않으면 출력 파일에서 행을 제외합니다.

두 개의 열로 구분된 파일이 있고 두 파일 모두에서 트랜잭션 식별자가 발견된 레코드만 포함하는 두 개의 새 파일을 만들어야 합니다. 식별자는 9열부터 14열까지의 필드에 있지만 각 파일의 각 레코드에는 9~14 범위 전후에 고유한 데이터가 있으며 가변 데이터를 출력 파일로 전송해야 합니다. 각 식별자는 한 번만 나타나거나 전혀 나타나지 않도록 보장됩니다.

Python 스크립트를 사용하여 직접 작성할 수는 있지만 라이브러리에서 열로 구분된 파일에 대한 기본 지원은 많지 않으며 모든 *nix 시스템(저는 Ubuntu 20.04를 사용하고 있습니다)에는 특별히 다음을 위한 명령줄 유틸리티가 있어야 한다고 생각합니다. 이전 컴퓨팅 시대에 맞춰 제작되었기 때문에 이 문제는 간단하게 처리할 수 있습니다. 물론 도구가 너무 오래된 경우에는 Python 스크립트를 직접 작성합니다(열로 구분된 파일을 처리하는 패키지를 아는 경우는 제외).

당신의 도움을 주셔서 감사합니다.


예: 9-14열의 문자를 포함하는 줄이 각 파일에 있으므로 ID:525이 줄은 해당 출력 파일에 기록됩니다. 두 입력 파일 모두 다른 파일에서 찾을 수 없는 레코드를 가지고 있습니다.

입력파일 1.txt

Record1 ID:525 DATA A
Record2 ID:232 DATA B
Record3 ID:811 DATA C
Record4 ID:400 DATA D

입력 파일 2.txt

Record1 ID:448 DATA E
Record2 ID:525 DATA F

출력 파일 1.txt

Record1 ID:525 DATA A

출력 파일 2.txt

Record2 ID:525 DATA F

답변1

GNU awk(일명)는 Ubuntu 20.04에서 사용할 수 있으며 gawk해당 변수를 통해 고정 너비 데이터를 처리할 수 있습니다.FIELDWIDTHS

전임자. 가장 간단하게 말하면

$ cat input_file1.txt
Record1 ID:525 DATA A
Record2 ID:232 DATA B
Record3 ID:811 DATA C
Record4 ID:400 DATA D

그 다음에

$ gawk 'BEGIN{FIELDWIDTHS="8 6 *"} {print $2}' input_file1.txt
ID:525
ID:232
ID:811
ID:400

이를 바탕으로 다음과 같은 작업을 수행할 수 있습니다.

$ gawk '
  BEGIN {FIELDWIDTHS = "8 6 *"}
  BEGINFILE {outfile[ARGIND] = gensub("input","output","1",FILENAME)}
  NR==FNR {a[$2] = $0; next}
  ($2 in a){
    print a[$2] > outfile[1]
    print $0    > outfile[2]
  }
' input_file1.txt input_file2.txt

주다

$ head output_file?.txt
==> output_file1.txt <==
Record1 ID:525 DATA A

==> output_file2.txt <==
Record2 ID:525 DATA F

예시 보기GNU Awk 사용자 가이드: 4.6 고정 너비 데이터 읽기

답변2

각 행을 문자열 변수로 설정하면 이렇게 9~14열을 확인할 수 있습니다.

myLine="Record1 ID:525 DATA A"
echo ${myLine:8:6}

${myLine:8:6}열 9(인덱싱이 0에서 시작하므로 8+1)에서 시작하여 6자 앞으로 이동합니다.

그런 다음 각 파일에서 검사를 수행합니다(아마도 grep을 사용하여).


awk를 사용하여 두 번째 열(공백으로 구분된 문자 집합)을 가져오고 다른 파일에 대한 검사를 수행할 수도 있습니다.

내 생각에는 (테스트되지 않음) 다음과 같은 작업을 수행할 수 있습니다.

#!/bin/bash
// This is based on the example you gave, only using 2 input files

files=("input_file1.txt" "input_file2.txt")

out_baseName="output_file"
index=1
adder=1
for file in ${files[@]}; do
    for line in $(cat $file); do
        id_string=`echo $line | awk '{ print $2 }'` // gets the 2nd column "ID:525"

        for subfile in ${files[@]}; do
            if [ "$subfile" == "$file" ]; then
                continue
            fi
            
            if grep "$id_string" $subfile; then
               echo $line >> ${out_baseName}${index}.txt
               grep "$id_string" $subfile >> ${out_baseName}$(($index+$adder)).txt
               
               index=$(($index+1))
               adder=$(($adder-1))
            fi
        done
    done
done


답변3

첫 번째 방법 1:

수표 입력의 예로 열 2를 고려하여 이를 수행할 수 있습니다.

awk 'NR==FNR{a[$2];next}($2 in a){print $0}' inputfile1.txt inputfile2.txt  >output_file2.txt

awk 'NR==FNR{a[$2];next}($2 in a){print $0}' inputfile2.txt inputfile1.txt  >output_file1.txt

두 번째 방법:

awk 'NR==FNR{a[substr($0,9,6)];next}(substr($0,9,6) in a){print $0}' inputfile2.txt inputfile1.txt >output_file1.txt

awk 'NR==FNR{a[substr($0,9,6)];next}(substr($0,9,6) in a){print $0}' inputfile1.txt inputfile2.txt  >output_file2.txt

산출

cat output_file1.txt 
Record1 ID:525 DATA A

cat output_file2.txt 
Record2 ID:525 DATA F

관련 정보