web-dev-qa-db-ja.com

パターンの前に改行を挿入する方法は?

行の前に改行を挿入する方法ではありません。これは、行内のパターンの前に改行を挿入する方法を尋ねています。

例えば、

sed 's/regexp/&\n/g'

正規表現パターンの後ろに改行を挿入します。

どうすればパターンの前で同じことができますか?

入力ファイルの例を次に示します

somevariable (012)345-6789

になるはずです

somevariable
(012)345-6789
120
Dennis

私のバージョンのsedでは、他の回答の一部が機能しませんでした。 &\nの位置の切り替えは機能しました。

sed 's/regexp/\n&/g' 

編集:これは、gnu-sedをインストールしない限り、OS Xでは機能しないようです。

39
Dennis

これはbashで動作し、LinuxおよびOS Xでテストされています。

sed 's/regexp/\'$'\n/g'

一般に、$の後に単一引用符で囲まれた文字列リテラルが続く場合bashは、Cスタイルのバックスラッシュ置換を実行します。 $'\t'はリテラルタブに変換されます。さらに、sedは、改行リテラルをバックスラッシュでエスケープする必要があるため、\の前に$が必要です。最後に、シェルが解釈するようにドル記号自体を引用符で囲まないでください。したがって、$の前に引用符を閉じてから再度開きます。

編集:@ mklement0のコメントで示唆されているように、これも同様に機能します。

sed $'s/regexp/\\\n/g'

ここで何が起こりますか:sedコマンド全体がCスタイルの文字列になりました。つまり、sedのバックスラッシュは、改行リテラルを別のバックスラッシュでエスケープする前に配置する必要があります。読みやすくなっていますが、この場合、シェル文字列の置換を行うことはできません(再びitくなりません)。

157
mojuba

Sedでは、出力ストリームに改行を簡単に追加することはできません。継続行を使用する必要がありますが、これは厄介ですが、動作します:

$ sed 's/regexp/\
&/'

例:

$ echo foo | sed 's/.*/\
&/'

foo

詳細については、 here を参照してください。少し厄介なものが必要な場合は、sedの代わりにマッチグループでPerl -peを使用してみてください。

$ echo foo | Perl -pe 's/(.*)/\n$1/'

foo

$1は、グループが括弧で囲まれている正規表現で最初に一致したグループを指します。

32
Todd Gamblin

私のMacでは、次の例では改行の代わりに単一の「n」が挿入されます。

sed 's/regexp/\n&/g'

これは改行に置き換えられます:

sed "s/regexp/\\`echo -e '\n\r'`/g"
28
Roar Skullestad
echo one,two,three | sed 's/,/\
/g'
14
vivek

この場合、sedは使用しません。私はtrを使用します。

cat Somefile |tr ',' '\012' 

これはコンマを取り、キャリッジリターンに置き換えます。

9
user1612632

完全な Perl正規表現 サポート(sedで得られるものよりもはるかに強力です)を利用して、sedの場合と同様にPerlのワンライナーを使用できます。また、* nixプラットフォーム間での変動はほとんどありません-通常、PerlはPerlです。そのため、特定のシステムのバージョンのsedで必要な処理を実行する方法について心配する必要がなくなります。

この場合、次のことができます

Perl -pe 's/(regex)/\n$1/'

-peは、sedの通常の動作モードと同様に、Perlを「実行して出力」ループに入れます。

'は、シェルが干渉しないように他のすべてを引用します

正規表現を囲む()はグループ化演算子です。置換の右側の$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}'

ボーナスのヒント-pcreパッケージがインストールされている場合、pcregrepが付属します。これは、Perl互換の完全な正規表現を使用します。

8
Dan Pritts

うーん、エスケープされた改行はsedのより新しいバージョンで動作するようです(GNU sed 4.2.1があります)、

dev:~/pg/services/places> echo 'foobar' | sed -r 's/(bar)/\n\1/;'
foo
bar
4
gatoatigrado
echo pattern | sed -E -e $'s/^(pattern)/\\\n\\1/'

()のサポートでEl Capitanで正常に動作しました

3
Quanlong

Linuxで出力ストリームに改行を挿入するには、次を使用しました。

sed -i "s/def/abc\\\ndef/" file1

file1は次のとおりです。

def

Sedインプレース交換の前、および:

abc
def

Sedインプレース交換後。 \\\nの使用に注意してください。パターンの内部に"がある場合は、\"を使用してエスケープします。

3
Karthik

-vを使用してパターンを提供し、awkでこれを行うこともできます。

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
2
fedorqui

この質問に対するすべての回答を読んだ後、次のスクリプト例の正しい構文を取得するために多くの試みが必要でした。

#!/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

スクリプトは、単一のsedコマンドを使用して、ファイルの末尾に改行\nの後に別のテキスト行を追加します。

1
Xavier
sed -e 's/regexp/\0\n/g'

\はnullなので、式はnull(nothing)に置き換えられ、...
\ nは新しい行です

Unixのいくつかのフレーバーでは機能しませんが、それはあなたの問題の解決策だと思います。

echo "Hello" | sed -e 's/Hello/\0\ntmow/g'
Hello
tmow
1
tmow

sedでは、パターン内のグループを「\ 1」、「\ 2」などで参照できます。したがって、探しているパターンが「PATTERN」で、その前に「BEFORE」を挿入する場合、あなたは使用することができます

sed 's/(PATTERN)/BEFORE\1/g'

つまり.

  sed 's/\(PATTERN\)/BEFORE\1/g'
1
Steve B.

Red Hatのviでは、\ r文字のみを使用してキャリッジリターンを挿入できました。これは内部的に「sed」ではなく「ex」を実行すると考えていますが、同様であり、viはコードパッチなどの一括編集を行う別の方法です。例えば。中括弧の後の復帰を要求するifステートメントで検索語を囲みます:

:.,$s/\(my_function(.*)\)/if(!skip_option){\r\t\1\r\t}/

物事をより良くするためにいくつかのタブを挿入したことに注意してください。

0
Robert Casey

これは私のためにMACで動作します

sed -i.bak -e 's/regex/xregex/g' input.txt sed -i.bak -e 's/qregex/\'$'\nregex/g' input.txt

その完璧なものかどうか...

0
sam