最初の空行を2行の内容に置き換えるには?問題があると思います。vim sedで複数の空行を単一の空行に置き換えるしかし、これに適応する方法をよく理解していません。たとえば、私の入力ファイルが次のような場合:
% abd
% def
% jkl
% mno
sedコマンドで置き換えたい最初次の2行を含む空行(1つを含むghi
、もう1つを含む%
):
% abd
% def
% ghi
%
% jkl
% mno
答え1
Sed は改行以外の行全体と一致するため、空行は単なる空の文字列です。を使用して^
行の先頭と末尾を一致させることで、空行を一致させることができます$
。^$
次に置き換えてください% ghi\n%
。
sed 's/^$/% ghi\n%/'
% ghi
すでに既存の改行が保持されているため、1行%
と次の行で終わります。
編集する:一度だけ一致させると、式は少し複雑になります。私が知っている最も簡単な方法sed
は次のとおりです。
sed '0,/^$/ s/^$/% ghi\n%/'
代替エントリはアドレス範囲内に含まれます0,/^$/
。これは、「0と最初の一致する行の間の行にのみ次を適用する^$
」という意味です。代替式^$
もチェックされるため、実際に変更される唯一の行は、一致する最初の行、^$
つまり最初の空行です。
答え2
以下は、使用sed
せずに最初の空行のみを置き換える別の方法です。\n
右スピンドルまたはgnu sed
住所0拡大する:
sed '/^$/{ # if line is empty
x # exchange pattern space w. hold space
//{ # if pattern space is empty (means the hold buffer was empty)
s//%/ # replace it with a % character
h # overwrite hold space (so now hold space looks like this: ^%$)
s/$/ ghi/ # add a space and the string ghi after the %, then
G # append content of hold buffer to pattern space so now the
} # pattern space looks like this: ^% ghi\n%$
//!x # if pattern space is not empty it means a change was
} # already made so exchange back (do nothing)
' infile
短い冗談:
sed -e'/^$/{x;//{s//%/;h;s/$/ ghi/;G' -e'}' -e'//!x' -e'}' infile
正直なところ、これは次の人のためのケーキの一部ですed
:
ed -s infile <<< $'/^$/s//% ghi\\\n%/\n,p\nq'
ファイルをその場で編集して,p
置き換えました。w
答え3
注:これは、以下を要求した元の質問に対する答えです。
空の行を内容を2行に置き換える方法は?
これは「カメレオン」の質問に対する答えではありません。
sed '/^$/{i\
% ghi\
%
d
}'
sed
空白行が見つかったら、 " % ghi
"、" %
"2行を挿入して空白行を削除します。
コメントから
これにより構文エラーが発生します。
貝殻の代わりに本物の貝殻を使用すると、長期的にすべての人の悲しみを減らすことができます。sed -f sed.script
Cシェルでこれを行うには他の方法がありますが、次のように機能します。
echo '/^$/{\' > sed.script
echo '% ghi\' >> sed.script
echo '%' >> sed.script
echo 'd' >> sed.script
echo '}' >> sed.script
sed -f sed.script data.file
rm -f sed.script
答え4
sed -e1\!b -e:n -e"/^$/c$(printf '\\\n%%%s' \ ghi '')" -en\;bn
sed
標準出力にスクリプト化された固定文字列を作成するための3つの基本要素を理解します。 3つすべてがスクリプトからバックスラッシュにエスケープされた改行の直後に始まり、スクリプトでエスケープされていない改行が最初に表示される場所、またはスクリプトに最初に表示されるファイルの末尾で終了します。
i
i
標準出力に固定文字列を挿入する今
a
a
次の行サイクルの前にスクリプトが発生する順序で、または最後の行の場合、この行の最後に固定文字列がstdoutに追加されるようにソートします。
c
- すべてのアドレスのパターン空間を削除
(1(,2)?)?
、現在のラインサイクルを終了し、c
すべてのアドレスの最後の固定文字列[es]の出力を一時停止します。
- すべてのアドレスのパターン空間を削除
printf '\n\n\n\n\n' |
sed -e1\!b -e:n \
-e"/^$/c$(printf '\\\n%%%s' \ ghi '')" \
-en\;bn
%地理 %
したがって、このスクリプトは、b
st以外のすべての行に対してスクリプトを拡張しますが、最初の行から始めて空の行を固定文字列にリンクできるまで、空でないすべての行をextで上書きする前に自動的に印刷してループします。戻ります。やり直すには、extタグを使用してください。!
1
c
n
:n