次のファイルがあります
'ABC'|filler|'Y'|'john/1'|'text'
'ABC'|filler|'Y'|'john/1'|'te/xt'
'ABC'|filler|'N'|'mary/2'|'text'
'DEF'|filler|'N'|'jane/3'|'text'
初期のgrep以降、
$ wordY="'Y'|"
$ wordN="'N'|"
$ grep ABC test.txt | grep "$wordY\|$wordN'[[:alpha:]]+/"
戻ってくる
'ABC'|filler|'Y'|'john/1'|'text'
'ABC'|filler|'Y'|'john/1'|'te/xt'
'ABC'|filler|'N'|'mary/2'|'text'
/
今、名前だけを削除して新しい.txtファイルに保存したいと思います。
だから私の理想的な出力は
'ABC'|filler|'Y'|'john1'|'text'
'ABC'|filler|'Y'|'john1'|'te/xt' -- / should not be removed for 'te/xt'
'ABC'|filler|'N'|'mary2'|'text'
出力を取得するには、コマンドにどのように追加する必要がありますか?
ベストアンサー1
入力が|
フィールド区切り文字として使用される「単純な」CSVファイルであり、埋め込まれた区切り文字または改行付きのフィールドがないと仮定すると、それを使用して変更したい特定のawk
フィールドを処理できます。
$ awk -F '|' -v sq="'" 'BEGIN { OFS = FS } $1 == sq "ABC" sq { gsub("/","",$4); print } ' file
'ABC'|filler|'Y'|'john1'|'text'
'ABC'|filler|'Y'|'john1'|'te/xt'
'ABC'|filler|'N'|'mary2'|'text'
入力をフィールドを区切る改行区切りレコードとして読み取り-F '|'
ます。インラインスクリプトで一重引用符を処理するのは難しく、コードを読み取ることができないため、変数を一重引用符文字に設定することもできます。awk
|
awk
awk
sq
コードは、最初のフィールドの値があるレコードを検出し、'ABC'
そのレコードの場合(潜在的に)変更されたレコードを出力する前に、4番目のフィールドからスラッシュを削除します。
また、最初のフィールドデータをハードコーディングせずに検出したい文字列全体を変数(ここquery
)に渡すこともできます。
$ awk -F '|' -v query="'ABC'" 'BEGIN { OFS = FS } $1 == query { gsub("/","",$4); print } ' file
'ABC'|filler|'Y'|'john1'|'text'
'ABC'|filler|'Y'|'john1'|'te/xt'
'ABC'|filler|'N'|'mary2'|'text'
以下の説明(現在削除済み)に記載されているように、次のことができます。可能変更されたレコードの4列目に実際にスラッシュが含まれている場合にのみ出力されます。これはおそらく単純化する私たちのコマンドは次のとおりです。
awk -F '|' -v query="'ABC'" 'BEGIN { OFS = FS } $1 == query && gsub("/","",$4)' file
このgsub()
コマンドは置き換えられた数を返します。つまり、元の 4 番目のフィールドのスラッシュ数を返します。そうでない場合、関数はゼロを返し、その結果ロギングが発生します。いいえ印刷されます。
3番目のフィールドが次のようになりますか?'Y'
それとも、次のものを'N'
使用できますか?
awk -F '|' -v query="'ABC'" -v yn="^'[YN]'$" '
BEGIN { OFS = FS }
$1 == query && $3 ~ yn && gsub("/","",$4)' file
ここでは、3番目のフィールドが変数と一致する必要がある正規表現を渡し、awk
それyn
を使用して$3 ~ yn
テストを実行します。式はまたはと^'[YN]'$
一致します。'Y'
'N'