列 9-14 の文字が別のファイルに見つからない場合は、出力ファイルから行を除外します。

列 9-14 の文字が別のファイルに見つからない場合は、出力ファイルから行を除外します。

2つの列で区切られたファイルがあり、両方のファイルにトランザクション識別子が見つかったレコードのみを含む2つの新しいファイルを作成する必要があります。識別子は列9から14までのフィールドにありますが、各ファイルの各レコードには9から14の範囲の前後に固有のデータがあり、可変データを出力ファイルに転送する必要があります。各識別子は一度だけ現れるか、まったく現れないように保証されます。

私はPythonスクリプトを使って直接書くことができますが、ライブラリ内の列で区切られたファイルの基本的なサポートはあまりありません。以前のコンピューティング時代に合わせて作成されたため、この問題は簡単に処理できます。もちろん、ツールが古すぎる場合は、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を使用して2番目の列(スペースで区切られた文字セット)を取得し、他のファイルをスキャンすることもできます。

私の考えでは、(テストされていない)次のことを行うことができます。

#!/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

2番目の方法:

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

関連情報