sedは改行文字を置き換えることができますか?


42

sedおよび改行文字に問題はありますか?
次の内容のファイルtest.txtがあります

aaaaa  
bbbbb  
ccccc  
ddddd  

以下は機能しません。
sed -r -i 's/\n/,/g' test.txt

trはこれに使用できることを知っていますが、私の質問はなぜsedでは不可能なのかということです。

これがファイルを1行ずつ処理する副作用である場合、これが発生する理由に興味があります。grep新しい行を削除すると思います。sedは同じことをしますか?


1
この場合、sedは使用するのに最適なツールではない可能性があります(例:「tr」)。より直感的で、読みやすく、保守しやすく、パフォーマンスが優れている(特にビッグデータで)などのツールがあります。比較を見つけることができます:http
//slash4.de/blog/python/sed-replace-newline-or-python-awk-tr-perl-xargs.html

2
tr末尾,を追加し、終了していない行を出力します。ベストは、使用することですpaste代わりに:paste -sd , test.txt
ステファンChazelas

回答:


48

GNU sedを使用して提供されるPOSIXLY_CORRECT環境ではありません(単一行入力の場合):

sed -i ':a;N;$!ba;s/\n/,/g' test.txt

https://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-nから:

  1. ラベルを作成します :a
  2. を介してパターンスペースに現在および次の行を追加します N
  3. 我々は最後の行の前にある場合、作成されたラベルへの分岐が$!ba$!最後の行でそれを行うにはしない手段(1つの最後の改行がなければならないとして))。
  4. 最後に、置換により、パターンスペース(ファイル全体)上のすべての改行がコンマに置き換えられます。

これは、ことのsedれる問題は、このissue.Itである理由だけでラインを読んで、と改行文字(または最後の文字)を置き換えることができます理解することはできませんline.But Iによって行を読み込みことを示していると思われる
ジム・

1
@jim一致するバッファにないように見えますが、私はsedに堪能ではありません。おそらく他の誰かがそれについて明らかにすることができます。その特定の情報でQを拡張する必要があると思います。そうすれば、人々はそれを読みやすくなり、うまくいけば答えることになります。
アントン14

その結果、ba: Event not found
krb686

@ krb686あなたが言及している「これ」とは何ですか?sedこれらの正確なオプションを使用して上記のコマンドを実行しましたか?どのtest.txt ファイルに?sed(試用版sed --version)のバージョンは?
アントン

@アンソン申し訳ありませんが、私は「その」と言うつもりだったと思います。cshで!。興味深いことに、それでもまだうまくいきませんでした!し、.cshスクリプトで二重にエスケープする必要がありました。ですから、現時点では本当に問題はありませんが、なぜそうなるのか知っていますか?私のために働いたのはsed :a;N;$\\!ba;s/\n/ /g'
krb686

16

これはGNUで動作しますsed

sed -z 's/\n/,/g' 

-z 4.2.2以降に含まれています

NB。-z区切り文字をヌル文字(\0)に変更します。入力にヌル文字が含まれていない場合、入力全体が1行として扱われます。これには制限があります。

最後の行の改行が置き換えられないようにするには、元に戻すことができます。

sed -z 's/\n/,/g;s/,$/\n/'

(これはsed再びGNU 構文ですが、全体がGNUのみであるため問題ではありません)


3
これは、OPが望むものではないかもしれない末尾の改行も置き換えます...結果をmikeservのソリューションと比較します。
don_crissti

7

OracleのWebサイトから:

sedユーティリティは、ファイルを1行ずつ順次メモリに読み込むことで機能します。次に、その行に指定されたすべてのアクションを実行し、その行をメモリに戻し、要求された変更を加えて端末にダンプします。この1行に対してすべてのアクションが実行された後、ファイルの次の行を読み取り、ファイルの処理が完了するまでプロセスを繰り返します。

基本的に、これはsedが1行ずつ読み取るため、改行文字が一致しないことを意味します。

https://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-nからのソリューションは次のとおりです。

sed ':a;N;$!ba;s/\n/,/g'

または、ポータブルバージョン(;ジャンプマークラベルの後に連結しない)

sed -e ':a' -e 'N;$!ba' -e 's/\n/,/g'

その仕組みについての説明は、そのページで提供されています。


これを変更した形式を使用してVPNログを解析し、ユーザーを「認証済み」とタイムスタンプ情報を同じ行に配置しました。乾杯!
user208145

構文はGNU固有であり、GNU sedを使用している場合でも、POSIXLY_CORRECTが環境にあり、入力に1行しかない場合、出力はないことに注意してください。
ステファンシャゼラス

5

sed\nパターンスペースを設定する直前に常に後続のewlineを削除し、スクリプトの結果を書き出す前に末尾のewlineを追加します。\newlineは、様々な手段によって、パターン・スペースにあったことができます-それは編集の結果ではないことはありません場合。これは重要です- パターンスペースの\newlinesはsed常に変更を反映し、入力ストリームには決して発生しません。\newlinesは、sedderが未知の入力で信頼できる唯一の区切り文字です。

すべての\newlinesをコンマで置き換えたい場合で、ファイルがそれほど大きくない場合は、次のことができます。

sed 'H;1h;$!d;x;y/\n/,/'

これは、すべての入力行をh古いスペースに追加します-最初の行を除き、代わりにh古いスペースを上書きします- \n改行文字に続きます。次に、出力d$!最後ではなくすべての行を選択します。最後の行で、H古いスペースとパターンスペースがx変更され、すべての\newline文字がy///コンマに変換されます。

大きなファイルの場合、この種の問題は問題を引き起こす可能性があります- sed行境界上ののバッファは、この種のアクションで簡単にオーバーフローする可能性があります。


2

または、少し単純な構文を使用できます。

sed ':a;N;s/\n/,/g;ba'

...シーケンスの順序を変更するだけです。


3
しかし、sますます大きくなっているパターンスペースで各入力行に対してコマンドを実行します。
ステファンシャゼラス

1

ここには非常に素晴らしいsedマジックがあります。また、パターンスペースのオーバーフローについていくつかの良い点があります。sedは非常にコンパクトで強力なので、最も単純な方法ではない場合でもsedを使用するのが大好きです。ただし、それには制限があり、大量のデータの場合、パターンスペースは不可解である必要があります。

GNUはこう言っています:

移植可能なsedスクリプトを作成する場合は、一部の実装が行の長さ(パターンおよびホールドスペース)を4000バイト以下に制限することが知られていることに注意してください。posix標準は、準拠するsed実装が少なくとも8192バイトの行長をサポートすることを指定しています。GNU sedには、行の長さに制限は組み込まれていません。より多くの(仮想)メモリをmalloc()できる限り、好きなだけ行をフィードまたは構築できます。
ただし、サブパターンと無期限の繰り返しを処理するために再帰が使用されます。これは、特定のパターンで処理できるバッファのサイズが利用可能なスタックスペースによって制限される可能性があることを意味します。

追加することはあまりありませんが、私のsedのガイドに向けて指摘したいと思います。素晴らしいです。 http://www.grymoire.com/Unix/Sed.html

ここに私の解決策があります:

for i in $(cat test.txt); do echo -n $i','; done; echo '' >> somewhere

うまくいく



-1

改行をに置き換えたいとします\n。私はそれをやりたかったので、ここで私がやったことです:

(echo foo; echo bar; echo baz) | sed -r '$!s/$/\\n/' | tr -d '\n' 
# Output: foo\nbar\nbaz

実行内容は次のとおりです。last、append を除くすべての行に対して\n。次に、で改行を削除しtrます。


-rsedBSDではなくGNU でのみ利用可能です。
ケノーブ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.