パターンの前にバックスラッシュと改行を挿入するにはどうすればいいですか?

パターンの前にバックスラッシュと改行を挿入するにはどうすればいいですか?

変数(a と仮定)に \n をキャプチャし、ファイル(abc.txt)内の検索パターンの前に $a を置き換えたいと考えました。

誰か解決策を提案してくれませんか?

> cat abc.txt
hi how are you how is your health
> echo $a
\

期待される出力 (検索パターン - how)

hi \
how are you \
how is your health

答え1

Bourneのようなシェルまたはrcのようなシェル

a='
' perl -pe 's/pattern/$ENV{a}$&/g' < abc.txt

は、改行文字を含むa環境変数をに渡し、の内容内のの各出現の前にその変数の内容を挿入します。perlperlpatternabc.txt

xBourne のようなシェルで変数以外の文字を割り当てるには'、次のようにします。

a='x'

バックスラッシュの場合:

a='\'

改行の場合:

a='
'

改行などの制御文字の場合、たとえばバックスペースやキャリッジリターンの場合はさらに悪くなり、コードの可読性が低下します。

$'...'ksh93では、エスケープ形式でこれらの文字を指定するための新しい形式の引用符が導入されました。 bashzshmkshFreeBSD などの他のシェルは、それ以降これshをコピーして拡張しました ($'\uXXXX'によって追加された形式などzsh)。

これらのシェルでは、以下を使用できます。

a=$'\n' a=$'\b' a=$'\r' a=$'\\' a=$'\''

改行、バックスペース、復帰、バックスラッシュ、または一重引用符の文字を割り当てます。

この引用演算子はまだ標準ではないため、移植可能なスクリプトでは使用できませんsh。標準的な代替方法としては、次の演算子を使用します。

a=$(printf '\b')

たとえば、バックスペースの場合は ですが、コマンド置換 ( $(cmd)) により の出力から末尾の改行文字が削除されるため、改行の場合は機能しませんcmd。次のようなハックに頼る必要があります。

nl=$(printf '\n.'); nl=${nl%.}

(つまり、 a を追加し.て後で削除する) ことで、それを保存できます。

はコード内でperlこれらの表記も理解するので、次のように実行できることに注意してください。\n

perl -pe 's/pattern/\n$&/g' < abc.txt

の GNU 実装sed(および最近のいくつかの他の実装) もこれをサポートしています。

sed 's/pattern/\n&/g' < abc.txt

sしかし、これは標準ではありません。標準的には、コマンドの置換部分の改行は、sedバックスラッシュの後に実際の改行が続く形で表現される必要があります。つまり、次のようになります。

backslash='\' newline='
'
sed "s/pattern/$backslash$newline&/g" < abc.txt

または変数なしの場合:

sed 's/pattern/\
&/g' < abc.txt

したがって、 の前にバックスラッシュと改行の両方を挿入したい場合は、pattern次のようになります。

sed 's/pattern/\\\
&/g' < abc.txt

合計 3 つのバックスラッシュ。2 つはリテラル バックスラッシュ用、1 つは改行用です。または、次のように指定しますperl

perl -pe 's/pattern/\\\n$&/g' < abc.txt

またはa変数を使用して:

a='\
' perl -pe 's/pattern/$ENV{a}$&/g' < abc.txt

答え2

次のようにして独自の bash コマンドを使用することもできます。

cat abc.txt | sed -e 's/how/\nhow/g' |  while read line; do echo "$line \\"; done

関連情報