web-dev-qa-db-ja.com

シェルスクリプトを使用して文字列から重複するすべての単語を削除する

私は次のような文字列を持っています

"aaa,aaa,aaa,bbb,bbb,ccc,bbb,ccc"

文字列から重複する単語を削除したい場合、出力は次のようになります

"aaa,bbb,ccc"

私はこのコードを試しました ソース

$ echo "zebra ant spider spider ant zebra ant" | xargs -n1 | sort -u | xargs

同じ値で正常に動作していますが、変数値を指定すると、重複するすべてのWordも表示されます。

重複する値を削除するにはどうすればよいですか。

[〜#〜]更新[〜#〜]

私の質問は、ユーザーが同じ場合、対応するすべての値を単一の文字列に追加することです。このようなデータがあります->

   user name    | colour
    AAA         | red
    AAA         | black
    BBB         | red
    BBB         | blue
    AAA         | blue
    AAA         | red
    CCC         | red
    CCC         | red
    AAA         | green
    AAA         | red
    AAA         | black
    BBB         | red
    BBB         | blue
    AAA         | blue
    AAA         | red
    CCC         | red
    CCC         | red
    AAA         | green

コーディングでは、すべての個別のユーザーをフェッチしてから、カラー文字列を正常に連結します。そのために、コードを使用しています-

while read the records 

    if [ "$c" == "" ]; then  #$c I defined global
        c="$colour1"
    else
        c="$c,$colour1" 
    fi

この$ c変数を出力すると、出力が表示されます(ユーザーAAAの場合)

"red,black,blue,red,green,red,black,blue,red,green,"

重複する色を削除したい場合、希望する出力は次のようになります

"red,black,blue,green"

この望ましい出力のために、私は上記のコードを使用しました

 echo "zebra ant spider spider ant zebra ant" | xargs -n1 | sort -u | xargs

しかし、重複した値で出力を表示しています。

「赤、黒、青、赤、緑、赤、黒、青、赤、緑」ありがとう

12
Urvashi

もう1つawkをお楽しみください。

$ a="aaa bbb aaa bbb ccc aaa ddd bbb ccc"
$ echo "$a" | awk '{for (i=1;i<=NF;i++) if (!a[$i]++) printf("%s%s",$i,FS)}{printf("\n")}'
aaa bbb ccc ddd 

ちなみに、あなたのソリューションでさえ変数でうまく機能します:

$ b="zebra ant spider spider ant zebra ant" 
$ echo "$b" | xargs -n1 | sort -u | xargs
ant spider zebra
12
George Vasiliou

trsortおよびuniq

echo "zebra ant spider spider ant zebra ant" | tr ' ' '\n' | sort | uniq

または

echo "zebra ant spider spider ant zebra ant" | tr ' ' '\n' | sort | uniq | xargs 

1行取得する

9
Michael D.
$ echo "zebra ant spider spider ant zebra ant"  | awk -v RS="[ \n]+" '!n[$0]++' 
zebra
ant
spider
8
JJoao

Gnu sedの場合:

sed ':s;s/\(\<\S*\>\)\(.*\)\<\1\>/\1\2/g;ts'

追加できます;s/ */ /g重複したスペースを削除します。

このような機能:Wordがこの行で2回目である場合は、それを削除して、重複がなくなるまでやり直します。

2
Philippos
Perl -lane '$,=$";print grep { ! $h{$_}++ } @F'
2
user218374

必須のawkソリューション:

$ echo "ant zebra ant spider spider ant zebra ant" | 
   awk -vRS=" " -vORS=" " '!a[$1] {a[$1]++} END{ for (x in a) print x;  } ' ; echo
zebra ant spider 

(最後のechoは改行用です)

2
ilkkachu

Python

オプション1

#!/usr/bin/env python
# get_unique_words.py

import sys

l = []
for w in sys.argv[1].split(','):
  if w not in l:
    l += [ w ]
print ','.join(l)

実行可能にしてから、Bashから呼び出します。

$ ./get_unique_words.py "aaa,aaa,aaa,bbb,bbb,ccc,bbb,ccc"
aaa,bbb,ccc

または、Bash関数として実装することもできますが、構文が乱雑です。

get_unique_words(){
  python -c "
l = []
for w in '$1'.split(','):
  if w not in l:
    l += [ w ]
print ','.join(l)"
}

オプション2

このオプションは、必要に応じてワンライナーにすることができます。

#!/usr/bin/env python
# get_unique_words.py

import sys

s_in = sys.argv[1]
l_in = s_in.split(',') # Turn string into a list.
set_out = set(l_in) # Turning a list into a set removes duplicates items.
s_out = ','.join(set_out) 
print s_out

バッシュで:

get_unique_words(){
  python -c "print ','.join(set('$1'.split(',')))"
}
1
wjandrea
cat filename | awk '{ delete a; for (i=1; i<=NF; i++) a[$i]++; n=asorti(a, b); for (i=1; i<=n; i++) printf b[i]" "; print "" }' > newfile
0

fileというファイルの元の表形式データを使用する:

sed '1d' file | sort -u |
awk '{ color[$1] = ( color[$1] == "" ? $3 : color[$1] "," $3 ) }
     END { for (user in color) print user, color[user] }'

これにより

CCC red
BBB blue,red
AAA black,blue,green,red

パイプラインの3つのステップ:

  1. sedコマンドは、読みたくないヘッダーである最初の行を削除します。
  2. sortコマンドは、独自の行を提供します。 sortの後のサンプルデータは次のようになります。

    AAA         | black
    AAA         | blue
    AAA         | green
    AAA         | red
    BBB         | blue
    BBB         | red
    CCC         | red
    
  3. awkコマンドはこのデータを取得し、配列color(ユーザー名は配列のキー)に各ユーザーのカンマ区切りの文字列を生成します。最後に(ENDブロック内)、収集されたすべてのデータが出力されます。
0
Kusalananda