両方のファイルに単一のレコードしかない場合ではなく、両方のテキストファイルの複数行にawkスクリプトを拡張する

Dec 01 2020

私は、この生成できる3 .txtの出力を

AA;BB;CC;DD;

2つのテキストファイルから。両方のファイルには単一のレコードしかありません

1 .txt

AA;BB;

2 .txt

CC;DD;BB;AA;

このawkスクリプトを使用します。

BEGIN{
  FS=OFS=";"
}
{
  for(i=1;i<=NF;i++){
    if(!seen[$i]++){ val=(val?val OFS:"")$i }
  }
  print val
  delete seen
  val=""
}

私はこのように使用し、pasteコマンドを使用して両方のファイルを結合し、awkコマンドでその出力を処理します。

paste 1st.txt 2nd.txt | awk -f tst.awk > "3.txt"

しかし、私は何が欲しいですか?
1つのレコードをもっと検討する必要があります。私はこのスクリプトをこの状況に適応させようとしています。これで、両方のファイルに1つのレコードだけが含まれていないことがわかります。

1 .txt

UU;    
AA;BB;
ZZ;KK;

2 .txt

CC;DD;BB;AA;
LL;KK;
GH;ZZ;SS;

出力3 Iが生成しようという.TXTはこれです

UU;
AA;BB;CC;DD;
ZZ;KK;LL;GH;SS;

処理ロジック:

上記のコードは、配列インデックスのハッシュルックアップでリテラル文字列を使用するだけなので、入力に含まれる文字は関係ありません。
しかし、サンプルの出力について:であれば2 .txtの共通フィールドがでもある1例.txt.for BB;AA;、あなたが一列にそれらを連結する必要が、すなわちAA;BB;CC;DD、順序付けは必要ありません。たとえば、出力が次の場合は関係ありません。必要なBB;AA;DD;CC;条件は、同じ行のフィールドの重複を避けることだけです。

私が「重複を避ける」と言うとき、私はこの出力を避けることを意味します

AA;BB;CC;DD;BB;AA;

出力は

AA;BB;CC;DD;

回答

4 User Dec 01 2020 at 15:23

多分これはあなたが望むものです:

BEGIN{FS=OFS=";"}
{sub(/;$/,"")} NR==FNR{ for (i=1;i<=NF;++i) for (j=1;j<=NF;++j) if (j!=i&&!b[$i,$j]++) a[$i,++c[$i]]=$j
    next
}
{
    delete b
    for (i=1;i<=NF;++i)
        ++b[$i] for (i=1;i<=NF;++i) for (j=1;j<=c[$i];++j)
            if (!b[a[$i,j]]++) $(NF+1)=a[$i,j]
    print
}

次のように使用します。

awk -f script.awk 2.txt 1.txt

ここにいくつかの以前の質問があります(おそらくあなたのもの-あなたはそれらを調べてあなたの質問を正しくする方法に取り組みたいかもしれません):

  • https://superuser.com/q/1600078
  • awk:データを生成するときに、行の順序を保持し、重複する文字列(ミラー)を削除します
  • https://superuser.com/q/1600557
  • https://superuser.com/q/1601402
  • https://superuser.com/q/1602713
  • https://stackoverflow.com/q/64929865
  • https://superuser.com/q/1604046
  • awkの動的正規表現
  • awkスクリプトの実行後の文字列の切り捨て