Mac OS Xのsedの改行


44

私は見つける\n具体的には、私は言葉を壊したくはMac OS Xでのsedで仕事を言っていない行に半角スペースで区切って:

# input
foo bar

私が使う、

echo "foo bar" | sed 's/ /\n/'

しかし、結果は愚かです、\n逃げられません!

foonbar

Googleに相談した後、回避策を見つけました。

echo 'foo bar' | sed -e 's/ /\'$'\n/g'

記事を読んだ後、私はまだ何を\'$'\n/g'意味するのか理解できません。誰かがそれを私に説明できますか、またはそれを行う他の方法がありますか?ありがとう!


これはおそらく、仕事とあまりにも:echo "foo bar" | tr ' ' '\n'
グレン・ジャックマン

3
アドバイスをありがとう。しかし、現在私は上記のケースを例として使用しているだけ\nです。
イヴァンZGシャオ

回答:


27

次のことが可能brew install gnu-sedとの呼び出しを置き換えるsedgsed

「g」の前に付加したくないsed場合はbrew install gnu-sed --with-default-names、を呼び出してくださいsed

(編集:醸造フラグの更新、クレメントへの帽子のヒント。)


すべてのプラットフォームで同じソフトウェアを使用することは、Macバージョンのすべての特性を扱うよりもずっと簡単です(ついに私にとって)。注意してください、オプションは今--with-default-namesはなく --default-names。ただし、このオプションはインストールで機能しなかったためalias gsed=sed、機能~/.profileさせるにはを配置する必要がありました。
クレメント

4
これはい回避策です。sedOS Xがそのように振る舞う理由を説明しておらず、gnu-sedより正確な誤った仮定をしています。長期的には問題を避けるために、GNU依存者にならず、POSIX標準に固執しないでください。
octosquidopus

AppleがOSをデフォルトで動作させる方法です。なぜプログラムの名前を使用し、それからそれを異なって動作させるのですか?私は...このための時間を無駄に
rascio

@rascio-OS XはBSDに似ていて、LinuxはLinuxに似ているからです。
iAdjunct

@rascio GNU sedが新参者であることがわかると思います。BSD sedは1979年に遡ります(en.wikipedia.org/wiki/Version_7_Unixを参照)。
ダンカン・ベイン

24

これらも機能します:

echo 'foo bar' | sed 's/ /\
/g'

echo 'foo bar' | sed $'s/ /\\\n/g'

lf=$'\n'; echo 'foo bar' | sed "s/ /\\$lf/g"

OS Xのsedは\n置換パターンでは解釈されませんが、行継続文字が前にあるリテラルの改行を使用できます。シェルは$'\n'、sedコマンドが実行される前にリテラルのラインフィードに置き換えられます。


4
なぜ機能するsed $'s/ /\\\n/g'が、機能しないのsed $'s/\\\n/ /g'か?
アレックジェイコブソン

1
@alec sed改行ごとに解析/分割されるため、linux / unixでも改行を削除することはできません。これをlinux / unixで実行しても、何も実行されませんecho -e 'foo\nbar' | sed 's/\n//'
。– wisbucky

10

回避策は、単一の引数文字列をに渡しますsed -e

その引数は、おなじみのsed s/ / /g形式の文字列になります。

その文字列は、次々に2つの部分で作成されます。

最初の部分は'...'形式で引用されています。

2番目の部分は$'...'形式で引用されています。

's/ /\'一部は剥ぎ取ら単一引用符を取得しますが、それ以外の場合は、コマンドライン上に見えるのと同様のsedに通過します。つまり、バックスラッシュはbashによって食べられるのではなく、sedに渡されます。

$'\n/g'一部には、ドル記号と剥離し、単一引用符を取得し、\n改行文字に変換されます。

まとめて、引数は

s / / \ newline/ g

[それは楽しかった。それを解くのにしばらくかかった。興味深い質問に対して+1。]


7

$'...'は拡張された標準エスケープシーケンスbashで生成される-ism ...です。\'直前のTh は、バックスラッシュの後に引用符で囲まれたセクションの終わりを意味するだけで、結果の文字列はs/ /\です (はい、文字列の途中で引用符を切り替えることができます;文字列を終了しません。)

POSIX標準は、検索パターンの一部としてsedのみ受け入れ\nます。OS Xは、sed厳密にPOSIX準拠のFreeBSDを使用しています。GNUはいつものように余分なものを追加し、Linuxユーザーはすべてそれが何らかの「標準」であると考えます(どちらかが標準プロセスを持っているなら、私はもっと感銘を受けるでしょう)。


今、私はその$'...'部分を理解しています。しかし...何s/ /\ ですか?どういう意味switch quotingですか?
イヴァンZGシャオ

2
'...'シェル引用の一種です。$'...'別です。そこにもあります"..."し、\x単一の文字を引用します。それらを単一の単語に組み合わせることができます。これはそこで行われていたことで、通常の''文字列から文字列に切り替えて$''を翻訳し\nます。残りについては、sedコマンドを構築しています(s/text/replacement/flags)。この場合、$'\n/g'追加されるリテラル改行を保護するために、最後にバックスラッシュを含むコマンドが開始されます。その結果、すべての(/gフラグ)スペースが改行に置き換えられます。
ギーコサウルス

1

何が起こっているかを視覚的に確認するのは非常に簡単です。文字列をエコーするだけです!

echo 's/$/\'$'\n/g'

結果として

s/$/\
/g

これは s/$/\newline/g

\前に余分な文字がなかった場合newline、シェルはnewlineコマンドの終了として早まって解釈します。

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