以下のようにタブ区切りの列テキストがあります。
A B1 B1 C1
B B2 D2
C C12 C13 C13
D D3 D5 D9
G F2 F2
上記の表を次のように変換するにはどうすればよいですか?
A B1 C1
B B2 D2
C C12 C13
D D3 D5 D9
G F2
実際のデータファイルを抽出しました。タブ区切りファイルです。あなた(Stéphane Chazelas?)が投稿したコマンドラインを試してみましたが、うまくいきますが、最後の列の重複エントリを削除できませんでした。
A CD274 PDCD1LG2 CD276 PDCD1LG2 CD274
B NEK2 NEK6 NEK10 NEK10 NEKL-4
C TNFAIP3 OTUD7B OTUD7B TNFAIP3 TNFAIP3
D DUSP16 DUSP4 DUSP8 VHP-1 DUSP8
E AGO2 AGO2 AGO2 AGO2 AGO2
出力は次のようにする必要があります
A CD274 CD276 PDCD1LG2
B NEK2 NEK6 NEK10 NEKL-4
C TNFAIP3 OTUD7B
D DUSP16 DUSP4 DUSP8 VHP-1
E AGO2
答え1
最初のサンプルデータセット:
$ awk -vOFS='\t' '{ r=""; delete t; for (i=1;i<=NF;++i) { if (!t[$i]++) { r = r ? r OFS $i : $i } } print r }' file
A B1 C1
B B2 D2
C C12 C13
D D3 D5 D9
G F2
2番目のサンプルデータセット(同じawk
スクリプト):
$ awk -vOFS='\t' '{ r=""; delete t; for (i=1;i<=NF;++i) { if (!t[$i]++) { r = r ? r OFS $i : $i } } print r }' file
A CD274 PDCD1LG2 CD276
B NEK2 NEK6 NEK10 NEKL-4
C TNFAIP3 OTUD7B
D DUSP16 DUSP4 DUSP8 VHP-1
E AGO2
スクリプトは入力ファイルを1行ずつ読み取り、各行ごとfile
に各フィールドを繰り返して出力行を作成しますr
。フィールドの値が出力行に追加されている場合(t
使用されたフィールド値のルックアップテーブルによって決まります)の場合、そのフィールドは無視され、それ以外の場合は追加されます。
入力行のすべてのフィールドが処理されると、構成された行が出力されます。
-vOFS='\t'
出力フィールド区切り文字はコマンドラインのタブに設定されます。
公開スクリプトawk
:
{
r = ""
delete t
for (i = 1; i <= NF; ++i) {
if (!t[$i]++) {
r = r ? r OFS $i : $i
}
}
print r
}
答え2
sed/tr、uniq、貼り付け
while read -r l; do sed 's/\t/\n/g' <<< "$l" | uniq | paste -s; done < test
またはPOSIX互換:
while read -r l; do echo "$l" | tr '\t' '\n' | uniq | paste -s -; done < test
ファイルの場合は、すべての文字を1行ずつ改行文字に置き換え、重複項目を削除し、改行文字を再文字に置き換えるために実行しますtest
。Tabuniq
Tab
$ cat test
A B1 B1 C1
B B2 D2
C C12 C13 C13
D D3 D5 D9
G F2 F2
$ while read -r l; do sed 's/\t/\n/g' <<< "$l" | uniq | paste -s; done < test
A B1 C1
B B2 D2
C C12 C13
D D3 D5 D9
G F2
気づく:このソリューションはいいえ複数行にわたる重複操作に使用されますC1
。
A B1 B1 C1
C1 B B2 D2
答え3
たぶん、次のようなものがあります。
gawk -vRS='\\s*\\S*' -vORS= '{$0=RT};$1!=prev;{prev=$1}'
RS=pattern
...トリックを使用すると、{$0=RT}
パターンに一致する部分として定義されたレコードを処理できます。
したがって、ここでは入力を<whitespace><non-whitespace>
$0
レコードに切り捨て(最初と唯一のフィールド)を<non-whitespace>
入力します。以前の記録と同じでない記録を$1
印刷しています。$1
次のように入力すると:
A B1 B1 C1
B B2 D2
C C12 C13 C13
D D3 D5 D9
G F2 F2
記録は次のとおりです
[A][ B1][ B1][ C1][ 雨][ B2][ D2][ C][ C12][ C13][ C13][ D] [D3] [D5] [D9] [ G][ F2][ F2][ ]
しかし、2番目の例では機能しません。一部の改行文字が削除されることがあります。
答え4
そしてperl
:
各行には固有の単語があります。
perl -MList::Util=uniq -lape '$_ = join "\t", uniq @F'
世界で唯一の言葉:
perl -lape '$_ = join "\t", grep {!$count{$_}++} @F'
または、2行目から始まる各単語行を検討してください。
perl -lape '$_ = join "\t", shift(@F), grep {!$count{$_}++} @F'