2017-09-12 16 views
0

ここで提案されている方法を適用しようとしました[Removing duplicates on a variable without sorting awkを使用して文字列内の重複を削除しました。awkを使用してbash文字列内の重複を削除する

例えば、我々は文字列(リンク以下の完全な説明)に次のコマンドを適用することで入手する必要があり、次のような出力

apple tree appleaplle 

を期待して、重複を削除

s="apple apple tree appleapple tree" 

があるとは、 。

awk 'BEGIN{RS=" "; ORS=" "}{ if(a[$0] == 0){a[$0]+=1; print $0}}' <<< $s 

しかし、私はこの

この最初の apple重複が必要に応じて、消去された
apple tree appleapple tree 

ではなく、最後のものを得る:それはこのように私たちは二度同じレコードを印刷するように期待していない、連想配列を使用しています。 実際に、各レコードの長さを出力すると、最後のレコードはtreeではなく、tree +戻り文字(私はそうだと思います)が表示されます。

$ awk 'BEGIN{RS=" "; ORS=" "}{ print length($0); print $0}' <<< $s 
$ 5 apple 5 apple 4 tree 10 appleapple 5 tree 

最後の木は連想配列方法を壊す結果として、実際に5つの文字ではなく4であることに注意してください。

なぜこの文字があり、どこから来たのか分かりません。 この方法を使用して重複を削除するにはどうすればこの問題を解決できますか?この例では、疑惑だ示す任意の提案

+1

使用 'OD -c scriptfile'あなたのファイルがCR + LFの行末を持っているかどうかを確認するために、そして' dos2unix'へ修正する。 –

+0

CR + LFの問題ではありません。これは簡単なパイロットエラーです。 –

答えて

2

あなたは語順を維持する必要がない場合:

$ (set -f; printf "%s\n" $s | sort -u | paste -sd" ") 
apple appleapple tree 

注文維持したいならば:" "

$ awk '                          
    {   
     delete seen 
     sep="" 
     for (i=1; i<=NF; i++) { 
      if (!seen[$i]++) { 
       printf "%s%s", sep, $i 
      } 
      sep=OFS 
     } 
     print "" 
    } 
' <<<"$s" 
apple tree appleapple 
+0

ありがとう。私はまだ種類と過去に精通していないので、2番目の答えに行くでしょう。あなたと@MarcLambrichsが別の答えで示唆するように、フィールドを使うと、この問題を回避するようです。それでも、私はまだレコードを使って何がうまくいかないのか分かりません。 – Moonpalacio

+2

レコードを使うアプローチの問題点は、 'RS =" "'を設定すると、行末の '\ n'が最後のフィールドの一部であり、' tree'が'ツリー\ n '。入力文字列の末尾に空文字を追加し、それを正しく引用するか( '<<<" $ s "')、 'RS ="の代わりに '' RS = "[[:space:]] +' 'を設定した場合、 「マルチキーRSのために後者がゴーク固有のものだと思ったのです。 –

+1

今、私は理解しています。実際、私は最後に余分な空白を追加しようとしましたが、それは動作していましたが、その '解決策'に満足していませんでした。問題は今明らかです。 – Moonpalacio

2

のためのあなたは非常に多くの

おかげで正しいです:

$ echo "apple apple tree appleapple tree" | awk '{for (i=1; i<=NF; i++) 
printf "%s %s\n", length($i), $i}' 
5 apple 
5 apple 
4 tree 
10 appleapple 
4 tree 

$ echo "apple apple tree appleapple tree" | awk 'BEGIN{RS=" "; ORS=" "} 
{ printf("%s |%s| ", length($0), $0)}' 
5 |apple| 5 |apple| 4 |tree| 10 |appleapple| 5 |tree 
| 

私はこのように、すべての異なる値を取得するためにFSを使用します

2倍を取り除くには:

echo "apple apple tree appleapple tree" | awk 'BEGIN{ORS=" "}{for (i=1; 
i<=NF; i++)a[$i]++} END {for (i in a) print i }' 
+0

ありがとう、はい、レコードの代わりにフィールドを使用してこれを達成するためのより良い方法と思われる – Moonpalacio

3

としてはすでにRSを設定することで、議論をすることを意味します\nはもはやレコード間の文字ではなく、入力行の最後のフィールドの一部になります"tree\n"

FWIWあなたはマルチchar型のRS用のGNU AWKを持っている場合、あなただけ行うことができます:

awk -v RS='\\s+' '!seen[$0]++{printf "%s%s", (NR>1?OFS:""), $0} END{print ""}' 
+1

あなたの説明の後に完全にクリア。謎は残っていない。そのメソッドを使用するには、レコードのマルチチャンク区切り文字が必要です。 – Moonpalacio

関連する問題