UNIX でパイプ区切りファイルを使用して各行に対して次の操作を実行する方法を探していますが、どこから始めればよいかわかりません。
- テキスト行内の文字を検索します (GREP を使用していると想定)
- 見つかった場合は、その行の末尾にテキストを追加します (SED を使用します)
- 見つからない場合は、同じ行の別の文字を探します
- 見つかった場合は行末にテキストを追加し、見つからない場合は何もしない
- ファイル内のすべての行をループする
何かアドバイスがあればいただければ幸いです。
答え1
これはすべてsed
作業であり、追加のツールは必要ありません。
foo
を含む行の末尾にを追加しf
、を含まないが を含むbar
行の末尾に を追加したいとします。f
b
sed '/f/{
s/$/foo/
b
}
/b/s/$/bar/'
を使用して行を「アドレス指定」できる/pattern/
ため、パターンが含まれている場合にのみ、次のコマンドが実行されます。したがって、例では、 を含む行のみが置換f
の実行をトリガーしs
、b
( は{}
コマンドをグループ化するため、アドレスが一致した場合にのみ内部のすべてが適用されます。 はb
、一致する に対して別の文字列が追加されないように、スクリプトの最後に分岐しますb
。
分岐なしの異なるアプローチ:
sed '/f/s/$/foo/;s/^[^f]*b[^f]*$/&bar/'
練習として、ある程度のsed
知識があれば、man sed
必要に応じて使用して、これを自分で理解することができます。
答え2
両方のシナリオの行末に同じテキスト文字列 (検索する文字: 'X' 'Y') を追加する場合は、次のようにします。
sed -e 's/[XY].*/&__ADDEDTEXT__/' yourfile
一方、文字に応じて行末に別々のテキストを配置したい場合は、次のようにします。
sed -e '
/X/s/$/__TEXT1__/; t
/Y/s/$/__TEXT2__/
' yourfile
ここでは、(test として読み取る) コマンドを使用して、t
前のコマンドが成功したかどうかを検出しs///
、現在の行の sed コードの末尾にジャンプします。また、構文に注意してください: /regex/s/// => 行が正規表現で構成されている場合は、その行で置換を実行します。
答え3
Perl は、すべてを一度に簡単に実行できる便利なツールでもあります。
したがって、@Philippos の例では、Perl プログラムは次のようになります (一部の構文はオプションであり、説明のために追加されています)。
perl -pe '(m/f/&&s/$/foo/)||(m/b/&&s/$/bar/)' file
これは結果を読み取って出力します。の代わりにfile
を使用することで、ファイルをその場で「編集」することもできます(は「その場で」を意味します)。つまり、-pi -e
-pe
-i
perl -pi -e '(m/f/&&s/$/foo/)||(m/b/&&s/$/bar/)' file
おそらく、awk
最初のテストでは失敗しましたが (私は AWK にそれほど精通していません)、Ruby (ほとんど同じように見えますが、例が必要な場合は私に連絡してください) でこれを行う方法があり、純粋な Bash でも楽しいかもしれません。