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=