別のファイルの区切り読みで各行を分割し、すべての分割単語の組み合わせを結果ファイルに保存します。

別のファイルの区切り読みで各行を分割し、すべての分割単語の組み合わせを結果ファイルに保存します。

names私はファイルの各区切り文字でファイルの各行を分割しdelim、独自の単語化合物を結果ファイルに保存したいと思いますcompoundsnames分割されていない行は出力ファイルから削除する必要があります。区切り記号は4つだけです。-'+

重要namesファイルにUTF-8でエンコードされた人の名前が含まれています。

$ cat delims
 (space is here)
-
'
+
$ cat names
Tania
Günter
Abdel+Aziz
Abdel'Piza
Märie-Pierre

出力複合ファイルは次のようにする必要があります(順序は重要ではありません)。

Abdel
Aziz
Piza
Märie
Pierre

答え1

フィールド区切り文字が正規表現を拡張できるようにする awk がある場合は、次の操作を実行できます。

$ awk '
    BEGIN{FS=""; while((getline < "delim") > 0){FS = FS=="" ? $0 : FS"|"$0}}
    NF>1 {for(i=1;i<=NF;i++) print $i}
' names
Abdel
Aziz
Abdel
Piza
Märie
Pierre

注:[ '+-]正規表現の代わりに文字セットを使用する方がきれいです|'|+|-(また、+リテラル数量子または正規表現数量子が使用されているかどうかを混乱させる可能性もなくなります)。ただし、-内部的に[...]開始または終了を除く範囲演算子があるため、項目を慎重に混在させる必要があります。

答え2

例の 4 文字については、安定して移植可能に動作します。

$ cat tst.awk
NR==FNR {
    FS = (NR > 1 ? FS "|" : "") "[" $0 "]"
    next
}
NF > 1 {
    for ( i=1; i<=NF; i++ ) {
        if ( !seen[$i]++ ) {
            print $i
        }
    }
}

$ awk -f tst.awk delims names
Abdel
Aziz
Piza
Märie
Pierre

これに必要な複雑さは、4つの区切り文字セットに3つのメタ文字があるためです。

  1. " "これは、FSで「すべての空白シーケンス」を意味します。
  2. "+"これは、正規表現で「前の式が1回以上繰り返される」ことを意味します(正規表現の先頭にあるか、それに続く場合は定義されていません|)。
  3. "-"最初または最後の文字ではなく、角括弧式内にある場合は、「範囲」を意味します。

したがって、意味が定義されておらず、単独で使用されている場合、意味が文字通りではないため、区切り文字の文字などの区切り|リストを作成することはできず、すべての項目を角括弧式で囲むこともできません。意味は から までの文字シーケンスです。 、再び文字通りの意味ではありません。|-|+|'+<blank>[ -+']-<blank>+

上記で私がしたことは、区切り文字に含めることができるすべての/すべての文字に対して機能する角括弧式の区切り|リストを作成することでした。[ ]|[-]|[+]|[']

答え3

greptrおよびsort:を使用してください。

注:ファイルの上下に-移動する必要があります(そうでない場合は範囲​​があると思います)。delimstr

区切り文字を含むすべての行をインポートし、すべてのgrep区切り文字を改行で置き換えます(改行delimsなしですべての文字をインポートするtr -d '\n' < delims)。

結果をパイプしてsort -u重複を排除し、出力をcompounds

grep -F -f delims names | tr -- "$(tr -d '\n' < delims)" '\n' | sort -u > compounds

出力:

$ cat compounds
Abdel
Aziz
Märie
Pierre
Piza

答え4

また、できます。

awk 'BEGIN{OFS=RS="";FS="\n"; getline;$1=$1;
       s=gsub("-","",$0);FS="["$0((s>0)?"-":"")"]";
       OFS=RS="\n"}
     NF>1{$1=$1; print}' delims names

Abdel
Aziz
Abdel
Piza
Märie
Pierre

ここでセットを1つ読み、RS再組み立てして予期しないスペースを追加しないようにします。FSgetlinedelims$0$1=$1OFS=""

次に、文字セットの終わりでのみ発生するようにいくつかの小さな調整を実行して(ifの末尾に追加することは成功した合計ですgsub)。$0--FSgsubs>0[ '+-]FS

これでリセットできRSますが。\nOFS\n

その後、いつでもどこでもビジネスを実行しますNF>1が、OFS="\n"繰り返す必要はないので、次のように再グループ化NFできます。$1=$1print

関連情報