特定の文字列を含むフィールドを削除する

特定の文字列を含むフィールドを削除する

file1特定の文字列(私の場合はアンダースコア文字)を含むフィールドのみを削除したいタブで区切られた複数のフィールドがあります(すべての行は削除しません_)。

cat file1
357M        2054_
357_        154=        1900_
511_        419X        1481_        34=

次の情報を取得したいと思います。

cat file2
357M
154=
419X        34=

次のようにこれらのフィールドを削除しました。

cat file1 | perl -pe 's/\w+_\s*//g'
357M    154=        419X        34=

しかし、列の数を変更したくないので、フォーマットが悪いです。

私も次のことを試しました。

cat file1 | sed 's/[0-9]*_//g'
357M
          154=
          419X         34=

しかし、その空の列を削除したいと思います。

実際に機能する無差別アプローチは次のとおりです。

cat file1 | sed 's/[0-9]*_//g' | tr -s '\t' '\t' | sed 's/^[ \t]*//g'
357M
154=
419X         34=

最後のコマンドは、(1)下線付きのすべてのフィールドを削除します。 (2)連続した複数のタブを1つのタブに置き換えます。 (3) 先行タブを削除します。それでもそれほどエレガントではありません。

どんな提案がありますか?

ベストアンサー1

考慮する:

sed 's/[^\t]*_//; s/\t[^\t]*_/\t/g' < input

これは2つの(条件付き)置換を実行します。

  • 1つ目は、「タブ以外の文字の後に下線が付くすべての(0個以上の)文字」を意味し、「(なし)」に置き換えられます。
  • 2番目は、「タブの後にタブ以外の文字(0個以上)の後に下線が付く」を「タブ」に置き換えることを意味し、その検索パターンが見つかった回数だけこれを行います。

削除する先行フィールドを見つけるには、最初の検索が必要です。 2番目の検索では、残りを削除します。

これにより、その列の元のフィールドが保持されます。

357M
        154=
        419X            34=

フィールドを完全に削除するには、検索にタブを含めてテキストを置き換えます。

sed 's/[^\t]*_\t//; s/\t[^\t]*_//g' < input

結果:

357M
154=
419X    34=

おすすめ記事