web-dev-qa-db-ja.com

edで連続する改行を削除する

入力ファイル:

1 line1\
2 line2\
3 line3\
4 \
5 line4\
6 \
7 \
8 line5\

必要な出力:

1 line1
2 line2
3 line3
4
5 line4
6
7 line5

POSIX edで可能ですか?

末尾の円記号を削除するのは簡単ですが、期待どおりの出力として連続する円記号を処理するにはどうすればよいですか?

2
user28512

これを一度に行う方法がわかりません。しかし、内容がよく知られている場合は、二重行に一意の文字列を追加できます。

# Add XX to lines that should be deleted
g/^$/+1s/^$/XX/
# Delete them
g/XX/d

あまりいいことではありません。

2
Runium

sedを使用すると、次のことができます。

_sed 's/\\$//;/./,/^$/!d'
_

edの主な問題の1つは、(別の時代の構文に加えて)スクリプトでのエラー処理です。

基本的に、ファイルの編集に成功した場合、edは成功を返すと考える必要があります。ただし、編集を成功させるには、各コマンドのアドレスを有効にし、各コマンドを成功させる必要があります(たとえば、sコマンドの場合、少なくとも1つの置換が行われることを意味します)。

したがって、この場合に編集が成功したことを確認したい場合は、注意が必要です。

@Sukminderのソリューションを構築し、コーナーケースをカバーしようとすると、次のように書くことができます。

_printf '%s\n' a a . 'g/\\$/s///' ',s/^/a/' 'g/^a$/+1,/./s/^a$//' \
  'v/./d' 'g/^a/s///' '$d' w | ed -s the-file
_

ファイルが空の場合(デフォルトのアドレス範囲(_1,$_)が無効になるため)、gコマンドは失敗します。そのため、最初にファイルの最後に行を追加する必要があります(aコマンドを使用)。_,s/\\$//_は、_\_で終わる行がない場合は失敗するため、そのような行(_g/\\$/s///_)がある場合にのみ実行する必要があります。

ここでは、入力に「xx」が見つからないと想定して「xx」を挿入する代わりに、各行の前に「a」を追加し、削除する行を後で削除する空の行に置き換えます。

うまくいけば、そのedスクリプトは、ファイルの書き込みに失敗した場合(wコマンドが失敗した場合)にのみゼロ以外の終了ステータスを返します。残念ながら、FSがいっぱいのときにファイルの書き込みに失敗すると、ed実装が成功を返すのを見てきました。

IMO、edは避けるのが最善です。現在、_Perl -pi.back_の使用は、移植性が高く、信頼性が高くなっています。

3