解決策がわからない難しい問題があります。
何百万行ものテキストを含むテキストファイルがあります。基本的には実行したいのですが、uniq
いくつかのバリエーションがあります。 2行が同じですが、サフィックスがある場合は、:FOO
サフィックスが欠落している行を削除します。しかし、ただそれ以外の場合、行が同じ場合。そしてただfor :FOO
、他の可能な接尾辞の代わりに。するいいえ/usr/bin/delta:FOO
上記の行が同じではないので削除したいと思います。
red.7
green.2
green.2:FOO
blue.6
yellow.9:FOO
green.2
下の行は同じですが、接尾辞がついて削除したいと思います。他のすべての行は変更されていないままにしてください。
[編集する:ファイルがすでに順番に整理されていることに言及するのを忘れました。 ]
これまで私の考え:
- 明らかに
uniq
これを行うツールです。 uniq
一つは無視してもいいプレフィックスしかし、決してサフィックス。 (これはとても迷惑なことです!)- 私はそれが
:
フィールドセパレータであるかのように偽装し、cut
(と一緒にpaste
)フィールドシーケンスを反転できると思いました。しかし、いいえ、cut
区切り文字がないと空白行を強制的に出力することは明らかに不可能です。 - 次のアイデアは、行を段階的に進め、サフィックスがあるかどうかに応じて1文字のプレフィックスを出力することです。しかし、これを高性能のBashループで書くことは想像できません。
どのようなヒントがありますか?
ただ使用することができます。本物この問題を解決するためのプログラミング言語の Bash で修正することは十分簡単ですが、うまくいきませんでした。
ベストアンサー1
最も簡単な場合は、行なしで削除するには削除してから:FOO
uniqを渡すだけです:FOO
。
$ sed 's/:FOO$//' file | uniq
red.7
green.2
blue.6
yellow.9
行を保持し:FOO
、接尾辞のない兄弟の後ろに常に来ると仮定する場合は、次のことを試すことができます。
$ rev file | sed 's/:/ /' | uniq -f1 | sed 's/ /:/' | rev
red.7
green.2:FOO
blue.6
yellow.9:FOO
rev
各行を右から左に印刷します。最初のフィールドを空白に置き換えると、sed
認識(またはこの場合)を無視する必要がある最初のフィールドとして使用できます。次の sed はその後に次のフィールドを配置し、最後のフィールドは左から再印刷されます。右。:
uniq
FOO
OOF
:
rev
残念ながら、文書が主張する内容にもかかわらず、uniq
フィールド区切り文字としてスペースやタブだけでなく、英数字ではなく、ほぼすべての文字を使用します。
$ printf 'foo/1\nfoo/2\nfoo%%3\nfoo:4\n'
foo/1
foo/2
foo%3
foo:4
$ printf 'foo/1\nfoo/2\nfoo%%3\nfoo:4\n' | uniq -f1
foo/1
これは、対応する文字がある場合、上記の回避策が機能しないことを意味します。あるいは、ファイルのすべてのインスタンスを削除し、結果を新しいインスタンスにgrep
パターンリストとして提供することで、次のことを回避できます。:FOO
:FOO
grep
$ grep -hFxv "$(grep ':FOO' file | cut -d: -f1)" file
red.7
green.2:FOO
blue.6
yellow.9:FOO