
変数(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
環境変数をに渡し、の内容内のの各出現の前にその変数の内容を挿入します。perl
perl
pattern
abc.txt
x
Bourne のようなシェルで変数以外の文字を割り当てるには'
、次のようにします。
a='x'
バックスラッシュの場合:
a='\'
改行の場合:
a='
'
改行などの制御文字の場合、たとえばバックスペースやキャリッジリターンの場合はさらに悪くなり、コードの可読性が低下します。
$'...'
ksh93では、エスケープ形式でこれらの文字を指定するための新しい形式の引用符が導入されました。 bash
、zsh
、mksh
FreeBSD などの他のシェルは、それ以降これ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