2016-04-13 22 views
1

私のbash-fooはちょっと錆びているので、ファイルから部分的な重複を除去する巧妙な方法があるかどうかを見たいと思っていました。私は、次の形式で数千行を含むファイルの束を持っている:テキストファイルから部分的な重複を削除する

String1|String2|String3|String4|String5|String6|...|String22|09-Apr-2016 05:28:03|x 

基本的に、それは最後の2列は、タイムスタンプとxはで、パイプで区切られた文字列の束です。私がしたいのは、すべてのファイルを連結し、すべての部分的な複製を削除することです。私は、String1からString22まで一致するファイル内の行として部分的な重複を定義していますが、タイムスタンプは異なる場合があります。例えば

、含むファイル:

String1|String2|String3|String4|String5|String6|...|String22|09-Apr-2016 05:28:03|x 
String1|String2|String3|String4|String5|String6|...|String22|09-Apr-2016 12:12:12|x 
String124|String2|String3|String4|String5|String6|...|String22|09-Apr-2016 05:28:03|x 

になるでしょう:

String1|String2|String3|String4|String5|String6|...|String22|09-Apr-2016 05:28:03|x 
String124|String2|String3|String4|String5|String6|...|String22|09-Apr-2016 05:28:03|x 

(選択されたタイムスタンプは関係ありません)。

アイデア?あなたがこれを行うことができawkを使用

答えて

3

awk '{k=$0; gsub(/(\|[^|]*){2}$/, "", k)} !seen[k]++' file 

String1|String2|String3|String4|String5|String6|String7|09-Apr-2016 05:28:03|x 
String124|String2|String3|String4|String5|String6|String7|09-Apr-2016 05:28:03|x 

awkコマンドは、最初の各ラインから最後の2つのフィールドを削除することで、変数kになります。次に、配列にseenという連想配列を使用し、kというキーで、各プロセスキーを配列に格納してkeyの最初のインスタンスのみを出力します。

0

あなたが連想配列をサポートしているのBashのバージョン4を、持っている場合、それは純粋なバッシュでかなり効率的に行うことができます。@anubhavaと

declare -A found 
while IFS= read -r line || [[ -n $line ]] ; do 
    strings=${line%|*|*} 
    if ((! ${found[$strings]-0})) ; then 
     printf '%s\n' "$line" 
     found[$strings]=1 
    fi 
done < "$file" 
+1

より慣用的だと思います'かなり効率的に'を '非常に非効率的に'置き換えます - これは、相当に大きなファイルに対して同等のawkスクリプトよりも1桁遅く実行されます。 [なぜシェルを使ってループを処理するかをテキストで判断する](http://unix.stackexchange.com/questions/169716/whyis-using-a-shell)を参照してください。 -loop-to-process-text-consider-bad-practice)を使用します。 –

0

同じ考えが、私は

$ awk -F'|' '{line=$0;$NF=$(NF-1)=""} !a[$0]++{print line}' file 

String1|String2|String3|String4|String5|String6|...|String22|09-Apr-2016 05:28:03|x 
String124|String2|String3|String4|String5|String6|...|String22|09-Apr-2016 05:28:03|x 
+1

これは慣用的ではありません(慣用配列の名前は 'seen []'で、フィールドリストをnullに設定するのは難しいでしょう)。 '$ 0'のすべての' | '空文字で 'ab | c'から' a | bc'を伝えることができなくなりました - 'a [$ 0] ++'で使われると、どちらも 'abc'になります。 –

関連する問題