4

次の形式のファイルがあります。

text   number   number   A;A;A;A;A;A
text   number   number   B
text   number   number   C;C;C;C;D;C;C;C;C

私がやりたいことは、4 番目の列のエントリの繰り返しをすべて削除して、次のようにすることです。

text   number   number   A
text   number   number   B
text   number   number   C;D

このファイルに対して行っている他のテキスト操作と一緒にパイプに収まるようにするには、ソリューションに bash スクリプトを使用することをお勧めします。

ありがとう!

4

4 に答える 4

3

を使用してこれを実現できawkます。; を使用して、フィールド 4 を配列に分割します。最初

awk '{delete z; d=""; split($4,arr,";");for (k in arr) z[arr[k]]=k; for (l in z) d=d";"l; print($1,$2,$3,substr(d, 2))}' file_name
于 2012-11-02T19:13:34.263 に答える
2

これはあなたのために働くかもしれません(GNU sed):

sed 's/.*\s/&\n/;h;s/.*\n//;:a;s/\(\([^;]\).*\);\2/\1/;ta;H;g;s/\n.*\n//' file
于 2012-11-02T19:09:42.440 に答える
2

タブ区切りの入力を想定すると、GNU 並列で次のようにすることができます。

parallel -C '\t' c4='$(echo {4} | tr ";" "\n" | sort -u | head -c-1 | tr "\n" ";");' \
                 echo -e '"{1}\t{2}\t{3}\t$c4"' :::: infile

出力:

text    number  number  A
text    number  number  B
text    number  number  C;D
于 2012-11-03T23:46:40.777 に答える
1

これも効くかも

awk -F";" '{
              delete words
              match($1,/[[:alpha:]]$/)
              words[substr($1,RSTART,RLENGTH)]++
              printf "%s",$1
              for (i=2;i<=NF;i++){
                if (!words[$i]++) printf ";%s",$i
              }
              printf "\n"
           }' file

ノート:

  1. はフィールドの区切りとして使用されるため;、前にいくつの列 (またはそれらの列にどの区切り記号が使用されているか) は関係ありません。A;A;A;A;A;A

  2. /[[:alpha:]]$//[^[:space:]]+$/単一のアルファベットの代わりに複数の非スペース文字に一致するように置き換えることができます。

  3. if (!words[$i]++) printf ";%s",$i連想配列のキーとして存在しない場合words、つまりwords[$i]0 の場合、列/文字を出力します。

于 2012-11-03T10:37:55.523 に答える