0

次の形式の行を含むテキストファイルがあります

*,[anything, even blanks],[dog|log|frog],[dog|log|frog],[0|1],[0|1],[0|1]

*大文字と小文字を区別しない)の値が同じである重複行を削除したいのですが、,[anything, even blanks],[dog|log|frog],[dog|log|frog],[0|1],[0|1],[0|1]

たとえば、ここにサンプルテキストファイルがあります

test,bar,log,dog,0,0,0
one
foo,bar,log,dog,0,0,0
/^test$/,bar,log,dog,0,0,0
one
FOO,,frog,frog,1,1,1

結果のテキストファイルでは、重複が削除されている必要がありますfoo(重複が削除され、1つが一意である限り、順序は重要ではありません)

test,bar,log,dog,0,0,0
one
/^test$/,bar,log,dog,0,0,0
one
FOO,,frog,frog,1,1,1

これを達成するために私ができる最も簡単なbashコマンドは何ですか?

4

5 に答える 5

5
awk -F, '!seen[tolower($1)]++' file
于 2012-11-15T20:54:30.050 に答える
1

あなたはこのawkようにこれを行うことができます(あなたは重複のどれが保持されるかを気にしないので):

awk -F, '{lines[tolower($1)]=$0}END{for (l in lines) print lines[l]}'

代わりに最初のものを保持したい場合:

awk -F, '{if (lines[tolower($1)]!=1) { print; lines[tolower($1)]=1 } }'
于 2012-11-15T19:31:46.437 に答える
0

検索する

(?:(?<=\n)|^)(.*)((?:,(?:d|l|fr)og){2}(?:,[01]){3})(?=\n)([\s\S]*)(?<=\n).*\2(?:\n|$)

...そしてに置き換えます

$1$2$3
于 2012-11-15T19:18:56.693 に答える
0
#!/bin/bash

for line in $(cat $1)
do
    key=$( echo ${line%%,*} | awk '{print tolower($0)}')

    found=0
    for k in ${keys[@]} ; do [[ "$k" == "$key" ]] && found=1 && break ; done
    (( found )) && continue

    echo $line
    keys=( "${keys[@]}" "$key" )
done

パフォーマンスの低いアソシエーション(ハッシュ)の代わりに配列を使用する。しかし、それはうまくいくようです。

于 2012-11-15T19:32:31.700 に答える
0

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

cat -n file | 
sort -fk2,2 |
sed -r ':a;$!N;s/^.{7}([^,]*),[^,]*(,(d|l|fr)og){2}(,[01]){3}\n(.{7}\1,[^,]*(,(d|l|fr)og){2}(,[01]){3})$/\5/i;ta;P;D' |
sort -n |
sed -r 's/^.{7}//'
  1. 各行に番号を付けます。
  2. 最初のキーで並べ替えます(大文字と小文字は区別されません)
  3. 重複を削除する(特定の基準に基づく)
  4. 縮小されたファイルを元の順序に並べ替える
  5. 行番号を削除する
于 2012-11-16T07:13:22.963 に答える