Sedコマンドを使って改行(\n
)を置き換えるにはどうすればいいですか?
私は失敗しました:
sed 's#\n# #g' file
sed 's#^$# #g' file
どうやって直すの?
このソリューションをGNU sed
と共に使用します。
sed ':a;N;$!ba;s/\n/ /g' file
これはファイル全体をループで読み込み、改行をスペースに置き換えます。
説明:
:a
でラベルを作成してください。N
を介してパターンスペースに追加します。$!ba
に分岐します($!
は、最後の改行が1つあるはずなので、最後の行では行わないことを意味します)。BSDとOS Xのsed
( @Benjieコメント )に従って動作する、クロスプラットフォーム互換の構文は次のとおりです。
sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' file
見ての通り、そうでなければ簡単な問題のためにsed
を使うことは問題が多いです。もっと簡単で適切な解決策は この答え を見てください。
代わりにtr
を使用しますか?
tr '\n' ' ' < input_filename
または改行文字を完全に削除します。
tr -d '\n' < input.txt > output.txt
またはGNUバージョン(長いオプション付き)がある場合
tr --delete '\n' < input.txt > output.txt
速い答え:
sed ':a;N;$!ba;s/\n/ /g' file
sedは最後の行に達するまでステップ1から3をループし、sedがすべての\ n文字を置換するパターンスペースにすべての行が収まるようにします
代替案:
sedとは異なり、すべての選択肢はプロセスを開始するために最後の行に到達する必要はありません
withbash、遅い
while read line; do printf "%s" "$line "; done < file
withPerl、sed-like speed
Perl -p -e 's/\n/ /' file
withtr、sedより高速、1文字のみで置換可能
tr '\n' ' ' < file
withpaste、tr-のような速度、1文字のみで置換可能
paste -s -d ' ' file
withawk、tr-like speed
awk 1 ORS=' ' file
"echo $(<file)"のような他の代替方法は低速で、小さなファイルでのみ動作し、ファイル全体を処理してプロセスを開始する必要があります。
sed FAQ 5.1 からの長答
5.10。\nエスケープを使用して改行を一致または削除できないのはなぜですか
シーケンス?\nを使用して2行以上の行を照合できないのはなぜですか?
\ nは行末の改行と決して一致しません。
改行は、行が配置される前に常に削除されます
パターンスペース。 2行以上をパターンスペースに入れるには、次を使用します。
「N」コマンドまたは類似のもの(「H; ...; g;」など)。
Sedは次のように機能します。sedは一度に1行ずつ読み取り、
改行を終了し、パターンスペースに残されたものを置きます。
sedスクリプトは、アドレス指定または変更が可能で、パターンスペースが
が出力され、stdout(またはファイル)に改行が追加されます。もし
パターンスペースは「d」または「D」で完全または部分的に削除されます。
このような場合、改行はnot追加されます。したがって、次のようなスクリプト
sed 's/\n//' file # to delete newlines from each line
sed 's/\n/foo\n/' file # to add a Word to the end of each line
末尾の改行が削除されるためbefore
行はパターンスペースに挿入されます。上記のタスクを実行するには、
代わりに次のスクリプトのいずれかを使用します。
tr -d '\n' < file # use tr to delete newlines
sed ':a;N;$!ba;s/\n//g' file # GNU sed to delete newlines
sed 's/$/ foo/' file # add "foo" to end of each line
GNU sed以外のsedのバージョンには、サイズの制限があるため
パターンバッファ、ここではUnix 'tr'ユーティリティを優先します。
ファイルの最後の行に改行が含まれている場合、GNU sedが追加されます
その出力の改行は、他のすべてを削除しますが、trは
すべての改行を削除します。
2行以上のブロックを一致させるには、3つの基本的な選択肢があります。
(1) 'N'コマンドを使用して、次の行をパターンスペースに追加します。
(2)「H」コマンドを少なくとも2回使用して、現在の行を追加します
ホールドスペースに移動し、ホールドスペースから行を取得します
x、g、またはGを使用。または(3)アドレス範囲を使用します(上記のセクション3.3を参照)
2つの指定されたアドレス間の行を一致させます。
選択肢(1)および(2)は、パターン空間に\ nを挿入します。
は、必要に応じてアドレス指定できます( 's/ABC\nXYZ/alphabet/g')。一例
「N」を使用して行ブロックを削除することは、セクション4.13に記載されています。
( "specific連続した行のブロックを削除するにはどうすればよいですか?")。この
例は、deleteコマンドを何かに変更することで変更できます
その他、「p」(印刷)、「i」(挿入)、「c」(変更)、「a」(追加)、
または 's'(代替)。
選択肢(3)はパターン空間に\ nを入れませんが、does
連続した行のブロックと一致するため、一致しない可能性があります
探しているものを見つけるために\ nも必要です。 GNU sed以来
バージョン3.02.80は、次の構文をサポートするようになりました。
sed '/start/,+4d' # to delete "start" plus the next 4 lines,
従来の「/ from here /、/ to there/{...}」範囲に加えて
アドレス、\ nの使用を完全に回避できる場合があります。
もっと短いawkの選択肢:
awk 1 ORS=' '
Awkプログラムは、条件付きコードブロックからなる規則で構成されています。
condition { code-block }
コードブロックを省略すると、デフォルトの{ print $0 }
が使用されます。したがって、1
は真の条件として解釈され、print $0
は各行に対して実行されます。
awk
は入力を読み込むとき、デフォルトでは改行であるRS
(Record Separator)の値に基づいてレコードに分割します。したがって、awk
はデフォルトで入力を行単位で解析します。分割には、入力レコードからRS
を取り除くことも含まれます。
これで、レコードを印刷するとき、ORS
(Output Record Separator)が追加され、デフォルトは改行になりました。そのため、ORS
をスペースに変更することで、すべての改行がスペースに変更されます。
gnu sedには、NULLで区切られたレコード(行)用のオプション-z
があります。あなただけ呼び出すことができます:
sed -z 's/\n/ /g'
誰がsed
を必要としますか?これがbash
のやり方です。
cat test.txt | while read line; do echo -n "$line "; done
ファイル全体をメモリに読み込まずに、awkを使ってすべての改行をスペースに置き換えるには、次のようにします。
awk '{printf "%s ", $0}' inputfile
最終改行が必要な場合
awk '{printf "%s ", $0} END {printf "\n"}' inputfile
スペース以外の文字を使用することができます。
awk '{printf "%s|", $0} END {printf "\n"}' inputfile
tr '\n' ' '
コマンドです。
シンプルで使いやすいです。
三つの事。
tr
(またはcat
など)は絶対に必要ありません。 (GNU)sed
と(GNU)awk
を組み合わせると、必要なテキスト処理の99.9%を実行できます。
stream!=行ベースed
は行ベースのエディタです。 sed
は違います。違いの詳細については sedの講義 を参照してください。ほとんどの人がsed
をラインベースであると混同します。なぜなら、デフォルトではSIMPLEマッチのパターンマッチングがそれほど貪欲ではないからです。グローバルコマンドで指定されていない限り、一致した場合に一致します。グローバルコマンドがSTREAMベースではなくラインベースであれば、一度にラインだけが評価されるため、グローバルコマンドもありません。 ed
を実行してみてください。違いに気付くでしょう。 ed
は、(forループのように)特定の行を反復処理したい場合には非常に便利ですが、ほとんどの場合はsed
が必要です。
それが言われている、
sed -e '{:q;N;s/\n/ /g;t q}' file
GNU sed
バージョン4.2.1ではうまく動きます。上記のコマンドは、すべての改行をスペースに置き換えます。入力するのは醜くて少し面倒ですが、それでもうまくいきます。 {}
は、健全性の理由で含まれているだけなので、除外することができます。
答え:ラベル...
sedを使って改行(\ n)を置き換えるにはどうすればいいですか?
...は、コマンドラインでfreebsd 7.2では機能しません。
(echo foo; echo bar)| sed ':a; N; $!ba; s/\ n//g' sed:1: ":a; N; $!ba; s/\ n// g":未使用のラベル' a; N; $!ba;/\ n//g' foo bar
しかし、sedスクリプトをファイルに入れるか、または-eを使用してsedスクリプトを「ビルド」しても問題ありません。
>(echo foo; echo bar)| sed -e:-e N -e '$!ba' -e '/\n//g' foo bar
または...
> cat > x.sed << eof
:a
N
$!ba
s/\n/ /g
eof
> (echo foo; echo bar) | sed -f x.sed
foo bar
おそらくOS Xのsedは似ています。
私はこの問題を抱えていました。キッカーは私がBSD(Mac OS X)とGNU(Linuxと Cygwin )sed
とtr
で動作するための解決策が必要だったということでした:
$ echo 'foo
bar
baz
foo2
bar2
baz2' \
| tr '\n' '\000' \
| sed 's:\x00\x00.*:\n:g' \
| tr '\000' '\n'
出力:
foo
bar
baz
(末尾に改行があります)
Linux、OS X、およびBSDUTF-8 サポートなし、または不安定な端末でも動作します。
改行を別の文字と交換するにはtr
を使用してください。
NULL
(\000
または\x00
)は、UTF-8サポートを必要とせず、使用される可能性も低いので、Niceです。
sed
を使用してNULL
を一致させる
必要ならばtr
を使って余分な改行を入れ替えます。
私はエキスパートではありませんが、sed
では、最初に次の行をパターンスペースに追加する必要があると思います。bijは "N
"を使用します。 sed&awk (Dale Dougherty and Arnold Robbins; O'Reilly 1997; page 107 in preview )の "Advanced sed commands"のセクション "Multiline Pattern Space"より:
Multiline Next(N)コマンドは、新しい行の入力を読み取り、それをパターンスペースの内容に追加することによって、複数行のパターンスペースを作成します。パターンスペースの元の内容と新しい入力行は改行で区切られています。埋め込まれた改行文字は、エスケープシーケンス "\ n"によってパターン内で一致させることができます。複数行のパターンスペースでは、メタ文字 "^"はパターンスペースの最初の文字と一致し、埋め込まれた改行の後の文字とは一致しません。同様に、 "$"はパターンスペースの最後の改行のみに一致し、埋め込まれた改行には一致しません。 Nextコマンドが実行された後、スクリプト内の後続のコマンドに制御が渡されます。
man sed
から:
[2アドレス] N
次の行の入力をパターンスペースに追加します。埋め込まれた改行文字を使用して、追加された素材と元の内容を区別します。現在の行番号が変わることに注意してください。
私は これを使用 (複数の)フォーマットが正しくないログファイルを検索するために使用します。検索文字列は "みなしご化された"次の行にあります。
上記の "tr"の解決策に対応して、Windows上で(おそらくGnuwin32バージョンのtrを使用して)提案された解決策は以下のとおりです。
tr '\n' ' ' < input
私のために働いていませんでした、それはエラーであるか、実際には何らかの理由で\ n w/''を交換しました。
Trの別の機能を使うと、 "delete"オプション-dはうまくいきました:
tr -d '\n' < input
または '\ n'ではなく '\ r\n'
私は、trを使って改行をタブに置き換え、次にタブを私が望むものに置き換えることによって、改行を回避するためにハイブリッドアプローチを使いました。この場合、 "
"私はHTMLブレークを生成しようとしているので。
echo -e "a\nb\nc\n" |tr '\n' '\t' | sed 's/\t/ <br> /g'`
状況によってはRS
を他の文字列や文字に変更できるかもしれません。このように、\ nはsub/gsubに対して利用可能です。
$ gawk 'BEGIN {RS="dn" } {gsub("\n"," ") ;print $0 }' file
シェルスクリプトの威力は、ある方法でそれを実行する方法がわからない場合は、別の方法で実行できることです。単純な問題に対して複雑な解決策をとるよりも、考慮すべきことがたくさんあります。
Gawkが遅いこと、そしてファイルをメモリに読み込むことに関しては、私はこれを知りませんが、私にとってgawkは一度に1行で動作するように見え、非常に高速です(他のものほど速くはありません)しかし、書いてテストする時間も重要です。
私はMB、さらにはGBのデータを処理しますが、私が見つけた唯一の制限は行サイズです。
POSIX sed は POSIXテキストファイル および POSIX行 の定義に従って入力する必要があるため、NULLバイトと長すぎる行は使用できず、各行は改行(最後の行を含む)で終わる必要があります。ライン)。これは、任意の入力データを処理するためにsedを使用するのを難しくします。
次の解決策はsedを避け、代わりに入力バイトを8進コードに変換してから再びバイトに変換しますが、8進コード012(改行)をインターセプトしてその代わりに置換ストリングを出力します。私が言うことができる限りソリューションはPOSIXに準拠しているので、それは多種多様なプラットフォームで動作するはずです。
od -A n -t o1 -v | tr ' \t' '\n\n' | grep . |
while read x; do [ "0$x" -eq 012 ] && printf '<br>\n' || printf "\\$x"; done
POSIXリファレンスドキュメント: sh 、 シェルコマンド言語 、 od 、 tr 、 grep 、 read 、 [ 、 printf 。
read
、[
、およびprintf
は、少なくともbashに組み込まれていますが、おそらくPOSIXでは保証されていないため、プラットフォームによっては、各入力バイトが1つ以上の新しいプロセスを開始し、処理が遅くなる可能性があります。一言で言えばこの解決策は約50キロバイト/秒に達するだけなので、大きなファイルには適していません。
Ubuntu(bash、dash、およびbusybox)、FreeBSD、およびOpenBSDでテスト済み。
あなたはxargs
を使うことができます - それはデフォルトでスペースで\n
を置き換えます。
しかし、あなたの入力がunterminated quote
の場合を問わず、それは問題を抱えているでしょう。特定の行の引用符が一致しない場合.
私が特に好きな解決策は、ホールドスペースにすべてのファイルを追加し、ファイルの終わりにすべての改行を置き換えることです。
$ (echo foo; echo bar) | sed -n 'H;${x;s/\n//g;p;}'
foobar
しかし、誰かが私に言ったいくつかのsedの実装ではホールドスペースは有限である可能性があります。
Awkを使う:
awk "BEGIN { o=\"\" } { o=o \" \" \$0 } END { print o; }"
純粋なtr
の解決策は単一の文字にのみ置き換えることができ、純粋なsed
の解決策は入力の最後の改行を置き換えません。次の解決策はこれらの問題を解決し、バイナリデータに対しては安全であると思われます(たとえUTF-8ロケールでも)。
printf '1\n2\n3\n' |
sed 's/%/%p/g;s/@/%a/g' | tr '\n' @ | sed 's/@/<br>/g;s/%a/@/g;s/%p/%/g'
結果:
1<br>2<br>3<br>
「普通の」置換の後に改行を入れるのは sed です。最初に改行文字を削除し、それからあなたの指示に従って処理し、そしてそれは改行を導入します。
sed を使用すると、各入力行について、トリムされた後の行の「末尾」(改行文字ではなく)を、任意の文字列に置き換えることができます。しかし、 sed は異なる行を出力します。たとえば、「行末」を「===」に置き換えたいとします(単一のスペースに置き換えるよりも一般的です)。
Prompt~$ cat <<EOF |sed 's/$/===/g'
first line
second line
3rd line
EOF
first line===
second line===
3rd line===
Prompt~$
改行文字を文字列に置き換えるには、前述のように非効率的に tr を使用して改行文字を "特殊文字"に置き換え、次に sed を使用して置き換えることができます。あなたが望む文字列を持つその特別な文字。
例えば:
Prompt~$ cat <<EOF | tr '\n' $'\x01'|sed -e 's/\x01/===/g'
first line
second line
3rd line
EOF
first line===second line===3rd line===Prompt~$
空行を削除するには:
sed -n "s/^$//;t;p;"
別のGNUsed
メソッド、 Zsolt Botykai 's answer とほぼ同じですが、これはsed
を使用しますあまり使用されないy
(transliterate)コマンド。これは1バイトのコード(末尾のg
)を保存します。
sed ':a;N;$!ba;y/\n/ /'
y
がs
よりも速く(おそらくtr
の速度で、20倍速く)実行されることを望みますが、GNU sed v4.2.2y
はs
よりも遅い4%です。
よりポータブルBSDsed
バージョン:
sed -e ':a' -e 'N;$!ba' -e 'y/\n/ /'
Mac OS X(FreeBSD sedを使用)の場合
# replace each newline with a space
printf "a\nb\nc\nd\ne\nf" | sed -E -e :a -e '$!N; s/\n/ /g; ta'
printf "a\nb\nc\nd\ne\nf" | sed -E -e :a -e '$!N; s/\n/ /g' -e ta
この方法も使えます
sed 'x;G;1!h;s/\n/ /g;$!d'
説明
x - which is used to exchange the data from both space (pattern and hold).
G - which is used to append the data from hold space to pattern space.
h - which is used to copy the pattern space to hold space.
1!h - During first line won't copy pattern space to hold space due to \n is
available in pattern space.
$!d - Clear the pattern space every time before getting next line until the
last line.
フロー:
最初の行が入力から取得されると、交換が行われるため、1がホールドスペースになり、\ nがパターンスペースになり、次にホールドスペースをパターンスペースに追加してから置換が実行され、パターンが削除されます。スペース。
2行目の交換の間に、2はホールドスペースに行き、1はパターンスペースに行き、そしてG
がホールドスペースをパターンスペースに追加し、そしてh
がそれにパターンをコピーしそして置換がなされそして削除される。この操作はeofに達するまで続けられ、正確な結果が表示されます。
@OP、ファイル内の改行を置き換えたい場合は、dos2unix(またはunix2dox)を使用することができます。
dos2unix yourfile yourfile
Allowedを使用して検索して置換します\ n
sed -ie -z 's/Marker\n/# Marker Comment\nMarker\n/g' myfile.txt
マーカー
になる
#マーカーコメント
マーカー
sed '1h;1!H;$!d
x;s/\n/ /g' YourFile
これは巨大なファイル(バッファ制限)では機能しませんが、ファイルを保持するのに十分なメモリがあれば非常に効率的です。 (@hilojackの良いコメントの後に訂正H
-> 1h;1!H
)
読み込み中に新しい行を変更する別のバージョン(より多くのCPU、より少ないメモリ)
sed ':loop
$! N
s/\n/ /
t loop' YourFile
あなたがWindowsの行末を処理しなければならないことに十分不幸なら、あなたは\r
と\n
を削除する必要があります。
tr '[\r\n]' ' ' < $input > $output
私はこの答えを投稿しました。私のUnixマシンではうまく動作しない上記のほとんどのsed
の推奨例を試してみて、エラーメッセージLabel too long: {:q;N;s/\n/ /g;t q}
が表示されたためです。最後に私は私の要求をし、そしてそれ故にすべてのUnix/Linux環境で働くここで共有しました: -
line=$(while read line; do echo -n "$line "; done < yoursourcefile.txt)
echo $line |sed 's/ //g' > sortedoutput.txt
最初の行はファイルyoursourcefile.txt
からすべての新しい行を削除し、単一行を生成します。そして2番目のsed
コマンドは、そこからすべてのスペースを削除します。
標準テキストエディタ を使用することもできます。
printf '%s\n%s\n%s\n' '%s/$/ /' '%j' 'w' | ed -s file
注:これは結果をfile
に保存します。
sed
と同様に、この解決法は最初にファイル全体をメモリにロードしなければならないという難点があります。
これはうまくいくかもしれません(GNU sed)。
sed 'H;$!d;x;:a;s/^((.).*)\2/\1 /;ta;s/.//' file
H
コマンドは、パターンスペースの前に改行を追加してから、結果をホールドスペースに追加します。通常のsedの流れは、各行から次の改行を削除することです。したがって、これはホールドスペースの先頭に改行を導入し、ファイルの残りの部分を複製します。ファイルがホールドスペースにまとめられたら、ホールドスペースをパッテンスペースと交換してから、パターンマッチングを使用してすべての元の改行をスペースに置き換えます。最後に、導入された改行を削除してください。
これにはsedコマンド内で実際に改行文字列を入力しないという利点があります。