回答:
この作品にbash
し、zsh
LinuxとOS X上でテストされ、:
sed 's/regexp/\'$'\n/g'
一般に、forの$
後に単一引用符で囲まれた文字列リテラルが続くと、bash
Cスタイルのバックスラッシュ置換$'\t'
が実行されます。たとえば、リテラルタブに変換されます。さらに、sedは、改行リテラルがバックスラッシュでエスケープされることを望んでいるため、\
before $
です。最後に、ドル記号自体は引用符で囲まないでください。シェルで解釈されるため、引用符を閉じる前に閉じ、$
再度開きます。
編集:@ mklement0のコメントで提案されているように、これも機能します。
sed $'s/regexp/\\\n/g'
ここで何が起こるか:sedコマンド全体がCスタイルの文字列になりました。つまり、改行リテラルが別のバックスラッシュでエスケープされる前に、sedがバックスラッシュを配置する必要があります。より読みやすいですが、この場合、シェル文字列の置換を(再び醜くすることなく)行うことはできません。
sed '\(first match\)\(second match\)/\1\'$'\n''\2/g'
。\ nの後の2つの一重引用符に注意してください。最初$
の行は" "セクションを閉じて、行の残りの部分が影響を受けないようにします。これらの引用符がなければ、\ 2は無視されました。
sed $'s/regexp/\\\n/g'
。これにより、読みやすさが向上します。唯一の注意点は、すべてのリテラル文字を2倍にする必要があることです\
。
他の回答の一部は、私のバージョンのsedでは機能しませんでした。位置を切り替える&
と\n
仕事をしました。
sed 's/regexp/\n&/g'
編集:をインストールしない限り、これはOS Xでは機能しないようですgnu-sed
。
brew install gnu-sed
続いてgsed 's/regexp/\n&/g'
echo 'alias sed=gsed' >> ~/.bashrc
sedでは、出力ストリームに改行を簡単に追加することはできません。面倒な継続行を使用する必要がありますが、機能します。
$ sed 's/regexp/\
&/'
例:
$ echo foo | sed 's/.*/\
&/'
foo
詳細はこちらをご覧ください。少し厄介なものが必要な場合はperl -pe
、sedの代わりに一致グループを使用してみてください。
$ echo foo | perl -pe 's/(.*)/\n$1/'
foo
$1
正規表現で最初に一致したグループを指します。グループは括弧内にあります。
perl -pi -e 's/(.*)/\n$1/' foo
s
関数呼び出しの置換部分で制御文字エスケープシーケンスをサポートしていません(GNU Sed実装とは異なります)。 。上記の回答は両方の実装で機能します。すべての違いの概要については、こちらを参照してください。
私のMacでは、以下は改行の代わりに単一の「n」を挿入します。
sed 's/regexp/\n&/g'
これは改行で置き換えられます:
sed "s/regexp/\\`echo -e '\n\r'`/g"
sed -i '' -e ...
を行っていて、^M
キャレットM(ctrl + m)がファイルに書き込まれるという問題がありました。私は同じパラメータを持つperlを使用してしまいました。
\n
)だけを使用します。
echo...
および改行なしで正常に動作しているにもかかわらず)、vimでこれを実行しただけです。
sed "s/regexp/`echo`/g"
-これはLF-CRではなく単一のLFを生成します
`echo`
するため、空の文字列になります。コマンド置換を使用して単一の改行を直接挿入する方法はありません(挿入\n\r
-つまり、追加のCR-はひどい考えです)。
echo one,two,three | sed 's/,/\
/g'
$'\n'
この場合、sedは使用しません。私はtrを使用します。
cat Somefile |tr ',' '\012'
これはコンマを取り、キャリッジリターンで置き換えます。
cat Somefile | tr ',' '\n'
YMMV
perlの正規表現を完全にサポートするという利点(sedで得られるものよりもはるかに強力です)を利用して、sedと同じようにperlワンライナーを使用できます。また、* nixプラットフォーム間での違いはほとんどありません-perlは通常perlです。そのため、特定のシステムのバージョンのsedを希望どおりに動作させる方法について心配する必要がなくなります。
この場合、次のことができます
perl -pe 's/(regex)/\n$1/'
-pe
perlをsedの通常の操作モードと同じように、「実行して印刷」ループに入れます。
'
シェルが干渉しないように他のすべてを引用します
()
正規表現を囲むのはグループ化演算子です。 $1
置換の右側には、これらの括弧内で一致したものがすべて出力されます。
最後に\n
、改行です。
括弧をグループ化演算子として使用しているかどうかに関係なく、一致させようとする括弧はエスケープする必要があります。したがって、上記のリストに一致する正規表現は次のようになります
\(\d\d\d\)\d\d\d-\d\d\d\d
\(
または\)
、リテラルの括弧と\d
一致し、数字と一致します。
より良い:
\(\d{3}\)\d{3}-\d{4}
中括弧内の数字が何をしているのか理解できると思います。
さらに、/以外の区切り文字を正規表現に使用できます。したがって、一致する必要がある場合は、エスケープする必要はありません。以下のどちらも、私の回答の冒頭の正規表現に相当します。理論的には、標準の/の代わりに任意の文字を使用できます 。
perl -pe 's#(regex)#\n$1#'
perl -pe 's{(regex)}{\n$1}'
いくつかの最終的な考え。
の-ne
代わりにを使用して-pe
も同様に動作しますが、最後に自動的に印刷されません。自分で印刷したい場合に便利です。たとえば、これはgrepに似ています(m/foobar/
正規表現の一致です)。
perl -ne 'if (m/foobar/) {print}'
改行の扱いが面倒で、魔法のように処理させたい場合は、を追加し-l
ます。ただし、改行を処理していたOPには役立ちません。
ボーナスのヒント-pcreパッケージがインストールされている場合は、pcregrep
完全なperl互換の正規表現を使用するが付属しています。
Linuxで出力ストリームに改行を挿入するには、以下を使用しました。
sed -i "s/def/abc\\\ndef/" file1
どこにfile1
あった:
def
sedインプレース置換の前、および:
abc
def
sedインプレース置換後。の使用にご注意ください\\\n
。パターンに"
内部がある場合は、を使用してエスケープし\"
ます。
sed
挿入します。---このコードは機能します。--- 、(CentOSリリース6.4 / Ubuntu 12.04.3)。\n
\\n
sed -i "s/def/abc\ndef/" file1
GNU sed version 4.2.1
GNU bash, version 4.1.2(1) / 4.2.25(1)
sedでは、パターン内のグループを「\ 1」、「\ 2」、...で参照できます。したがって、探しているパターンが「PATTERN」であり、その前に「BEFORE」を挿入したい場合、使用できる、エスケープしない
sed 's/(PATTERN)/BEFORE\1/g'
すなわち
sed 's/\(PATTERN\)/BEFORE\1/g'
これをawkで行うこともできます。これを使用-v
してパターンを提供します。
awk -v patt="pattern" '$0 ~ patt {gsub(patt, "\n"patt)}1' file
これは、ラインに特定のパターンが含まれているかどうかをチェックします。もしそうなら、それはその最初に新しい行を追加します。
基本的な例をご覧ください:
$ cat file
hello
this is some pattern and we are going ahead
bye!
$ awk -v patt="pattern" '$0 ~ patt {gsub(patt, "\n"patt)}1' file
hello
this is some
pattern and we are going ahead
bye!
これは行内のすべてのパターンに影響することに注意してください。
$ cat file
this pattern is some pattern and we are going ahead
$ awk -v patt="pattern" '$0 ~ patt {gsub(patt, "\n"patt)}1' d
this
pattern is some
pattern and we are going ahead
1
は、Awk ではの省略形として使用され{print $0}
ます。その理由は、Trueと評価されるすべての条件が、Awkのデフォルトアクションをトリガーし、現在のレコードを印刷することです。
この質問に対するすべての回答を読んだ後も、次のスクリプト例の正しい構文を取得するために多くの試みを行いました。
#!/bin/bash
# script: add_domain
# using fixed values instead of command line parameters $1, $2
# to show typical variable values in this example
ipaddr="127.0.0.1"
domain="example.com"
# no need to escape $ipaddr and $domain values if we use separate quotes.
sudo sed -i '$a \\n'"$ipaddr www.$domain $domain" /etc/hosts
スクリプトは\n
、単一のsed
コマンドを使用して、改行の後に別のテキスト行をファイルの最後に追加します。
sed '/regex/G'