perl:文字列を新しい行(改行文字)を含む変数に置き換えます。

perl:文字列を新しい行(改行文字)を含む変数に置き換えます。

メタ文字を含む編集をしたいと思います。ここhttps://stackoverflow.com/questions/29613304/is-it-possible-to-escape-regex-metacharacters-reliously-with-sed解決策の1つはvia perlwith s\Q ... \E(許可された答えのほぼ終わり)です。複数のスレッドを処理することが知られていますが、

echo 'a-b' > a.txt;from='-';to='\n';perl -s -0777 -pe 's/\Q$from\E/$to/' -- -from="$from" -to="$to" a.txt
a\nb
echo 'a-b' > a.txt;from='-';to='\n';perl -s -0777 -pe 's/\Q$from\E/\n/' -- -from="$from" -to="$to" a.txt
a
b

変数を介してそれ自体に書き込む場合にのみ改行に置き換えることができますが、s何らかの理由で機能しません。 Webで検索しても答えが出ませんね。変数を使用して機能させるにはどうすればよいですか\n

\nPS変数は長さに制限がなく、メタ文字を含めることができます。すべてのメタ文字は、改行文字に置き換えられる特定の文字シーケンス(例:1つ)を除いて、文字通り使用されます。

答え1

問題は正しいアプローチではなく、Perl次のことですshell

echo 'a-b' > a.txt
from='-'
to=$'\n' # <<< look at this
perl -s -0777 -pe 's/\Q$from\E/$to/' -- -from="$from" -to="$to" a.txt

出力

a
b

答え2

変数を前処理して、2つのステップでこれを行う方法を見つけたようです。

to="$(printf "%s" "${to}" | perl -pe 's/\Q\n\E/\n/g')"

驚くべきことに、これは単一のシンボル(改行)置換では機能しませんが、長い文字列では機能します。

echo 'a-b' > a.txt;from='-';to='\n';to="$(printf "%s" "${to}" | perl -p -e 's/\Q\n\E/\n/g')";perl -s -0777 -pe 's/\Q$from\E/$to/' -- -from="$from" -to="${to}" a.txt
ab
echo 'a-b' > a.txt;from='-';to='\nd';to="$(printf "%s" "${to}" | perl -p -e 's/\Q\n\E/\n/g')";perl -s -0777 -pe 's/\Q$from\E/$to/' -- -from="$from" -to="${to}" a.txt
a
db

今は長い文字列しかありませんが、なぜ単一のシンボルに対して失敗するのか疑問に思います。

次のようにファイルから変数の割り当てを読み取ると機能します。

itext="${line}"
itext="$(printf "%s" "${itext}" | perl -p -e 's/\Q\n\E/\n/g')"
while read -r line; do
    otext="${line}"
    otext="$(printf "%s" "${itext}" | perl -p -e 's/\Q\n\E/\n/g')"
    perl -s -0777 -pi -e 's/\Q$itext\E/$otext/' -- -itext="${itext}" -otext="${otext}" "${file_to_edit}"
done < "${file_with_edits}"

関連情報