sedで行末を検出する方法


15

を使用して、最後の文字が改行である場合にのみ置換を実行する方法を探していますsed

例えば:

lettersAtEndOfLine

置き換えられますが、これは次のようにはなりません

lettersWithCharacterAfter&

sedは改行ではうまく機能しないため、次のように単純ではありません。

$ sed -E "s/[a-zA-Z]*\n/replace/" file.txt

どうすればこれを達成できますか?

回答:


21

標準sedでは、ファイルから読み込まれたテキストに改行が表示されることはありません。これは、sed行ごとに読み取るため、sedのパターンスペースの現在の行のテキストの最後に改行がないためです。つまり、sed改行で区切られたデータを読み取ります。区切り文字は、sedスクリプトが表示するものの一部ではありません。

正規表現は、行の終わりにを使用して(または最初にを使用して)アンカーできます。行の最初/最後に式をアンカーすると、行のどこかだけでなく、そこに正確に一致するように強制されます。$^

[A-Za-z]*行末のパターンに一致するものを何かで置き換える場合は、次のようにパターンをアンカーします。

[A-Za-z]*$

...行の最後で一致し、他の場所では一致しません。

ただし、何に[A-Za-z]*$も一致しないため(たとえば、すべての行の末尾にある空の文字列)、何かを一致させる必要があります。たとえば、次のように指定します。

[A-Za-z][A-Za-z]*$

または

[A-Za-z]\{1,\}$

したがって、sedコマンドラインは次のようになります

$ sed 's/[A-Za-z]\{1,\}$/replace/' file.txt

-Eここではスイッチが必要ないため、ここでは使用しませんでした。それで、あなたは書くことができたでしょう

$ sed -E 's/[A-Za-z]+$/replace/' file.txt

それは好みの問題です。


コメントは詳細な議論のためのものではありません。この会話はチャットに移動しました
クサラナンダ

3
sed "s/[a-zA-Z]*$/replace/" input.txt > result.txt

または、長く複雑な不要な方法:

私は知っています、これはまだsedを使用して、trの助けを借りて実行できます。行の終わりを表す別の文字を割り当てることができます。別の一時文字、この場合は「 `」を使用する必要があります。行の終わりを表すために "〜"を使いましょう:

tr '\n' '`' <input.txt >output.txt
sed -i "s/`/~`/" output.txt
tr '`' '\n' <output.txt >result.txt

そして、実際の検索と置換を実行するには、「\ n」ではなく「〜」を使用します。

sed -i -E "s/[a-zA-Z]*~/replace/" result.txt

次に、他の行の余分な文字をクリーンアップします。

sed -i "s/~//" result.txt

明らかに、これはすべて一緒にパイプすることができ、次のような結果になります。

tr '\n' '`' <input.txt | sed -e "s/`/~`/" | tr '`' '\n' | sed -E -e "s/[a-zA-Z]*~/replace/" | sed "s/~//" > result.txt

3
よくわかりません...行末にアンカーしません$か?例s/[a-zA-Z]*$/replace/
don_crissti 2015年

1
2ポイント:1)後者は文字列の終わりにゼロ文字を許可するため、\+代わりに使用する方がよいでしょう。2)文字クラスを使用できます。だから:*[[:alpha:]]sed 's/[[:alpha:]]\+$/replace/' file
グレン・ジャックマン

@glennjackmanプラス前のバックスラッシュは何ですか?それは追加文字と一致しませんか?
Matthew D. Scholefield、2015年

1
-rオプションなしのGNU sed は、この正規表現構文を使用します
グレン・ジャックマン、2015年

0

あなたが投稿した(壊れた)コードスニペットから、あなたも改行を置き換えたいようです。その場合、正規表現のアンカーだけでは効果がありません。以下は解決策です:

sed '/[[:alpha:]]\+$/{N;s/[[:alpha:]]\+\n/replace/}' your_file

故障:

  • /[a-zA-Z]\+$/{} は、カーリーの内側にあるものをすべて、正規表現に一致する行に適用することを意味します。
  • 正規表現は、あなた自身の答えに見られるようにアンカーを使用するもので、glenn jackmanのコメントを考慮に入れるように変更されています。
  • カーリー内では、N「次の行をアクティブなバッファーに追加する」ことを意味します(sed「パターンスペース」と呼ばれるもの)
  • 最後に、s///ステートメントは必要な置換です。パターンスペースには2つの連続した行が含まれ、改行はその一部であるため、この方法は機能します。

0

行末を見つけるには、$記号を使用します

行末アンカーなし:

sed -n '/pattern/p' file 

行末アンカーなし:

sed -n '/pattern$/p' file
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.