スペースで区切られた2つの列を持つファイルがあります。 2番目の列にはT
orの1つだけがありますF
。最初の列の文字を読みたいです。たとえば、A
2 番目の列に同じ文字の 3 行がある場合は保持されますが、2 番目の列に混合文字がある場合は削除されます。T
A
B
D
A T
A T
A T
B T
B T
B F
C F
C F
D F
D T
D F
2番目のフィールドに同じ最初のフィールドのすべての行に値がある場合は、印刷したいと思います。予想出力:
A T
A T
A T
C F
C F
たぶんawk
それは可能ですか?助けてくれてありがとう!
答え1
1つの方法は次のとおりですawk
。
awk 'NR==FNR{if (x[$1]++){if ($2!=t){z[$1]++}} else {t=$2};
next}!($1 in z)' infile infile
このプロセスはファイルを2回処理します。最初のパスでは、最初のフィールドが同じ値の場合、2番目のフィールドの値が異なることを確認します。その$1
場合は配列インデックスとして使用され、2番目のパスは次の場合にのみバッチを印刷します。最初のフィールドはそのフィールドのインデックスではありません。または、次のように
使用しても大丈夫なら:sort
awk
sort -u infile | awk 'NR==FNR{seen[$1]++;next}seen[$1]==1' - infile
sort -u
ファイルから重複した行を削除し、結果をパイプしてawk
最初のフィールドの発生回数を計算し、ファイル全体を再処理し、数があれば行を印刷します1
。
答え2
sed -e '
# this is a do-while loop which collects lines till the time the first
# field remains the same. We break out of the loop when we see
# a line whose 1st field != prev lines 1st field **OR** we hit the eof.
:a
$bb
N
/^\(\S\+\) .\(\n\1 .\)*$/ba
:b
# all equal
# **Action:** Print and quit
/^\(\S\+ .\)\(\n\1\)*$/q
# all same 1st fld, but lines unequal, otw would have matched above
# **Action:** Drop the whole block as its uninteresting
/^\(\S\+\) .\(\n\1 .\)*$/d
# all equal, and trailing line part of next line
# **Action:** Display upto the last newline and restart
# with the trailing portion
/^\(\(\S\+ .\)\(\n\2\)*\)\n[^\n]*$/{
h
s//\1/p
g
}
# of same 1st fld but some lines unequal, and trailing portion has
# next line
# **Action:** strip till the last newline, and restart over with the
# trailing part
s/.*\(\n\)/\1/
D
' yourfile
これは「Sed」が扱う非常に興味深い問題です。しかし、私が見つけたのは良いことです。それとも、OTがSEによって提供されるより大きな入力セットであるべきですか?私の提案は、実際のサイズと種類のテストケースをhttp://pastebinサイトに配置できることです。これはこの種の作業に非常に役立ちます。
答え3
アクセス権がある場合GNUデータの混合、次のようにデータを縮小できます。
datamash -W groupby 1 countunique 2 collapse 2 < file
A 1 T,T,T
B 2 T,T,F
C 1 F,F
D 2 F,T,F
awk
これにより、次のような後処理が容易になります。
datamash -W groupby 1 countunique 2 collapse 2 < file |
awk '$2==1 {n = split($3,a,","); for (i=1;i<=n;i++) print $1, a[i]}'
A T
A T
A T
C F
C F
答え4
sed '
/\n/D
:1
$! {
N
/^\(\S\+\s\).*\n\1[^\n]\+$/ b1
}
/^\([^\n]\+\n\)\(\1\)\+[^\n]\+$/! D
h
s/\n[^\n]\+$//p
g
s/.*\n/\n/
D
' file