web-dev-qa-db-ja.com

sedを使用して改行(\ n)を挿入します

データベースのインポートのために、いくつかのリストを適切にフォーマットされたCSVファイルにスクラブしようとしています。

私の開始ファイルは、次のように複数の行にまたがる各「行」であるはずのこのようなものに見えます

Mr. John Doe
Exclusively Stuff, 186 
Caravelle Drive, Ponte Vedra
33487. 

ファイルをクリーンアップするsedスクリプトを作成しました(二重スペースやコンマの前後のスペースのような「ダーティ」フォーマットがたくさんあります)。 問題は、ピリオドのあるZipです。新しい行のためにそのピリオドを変更したいのですが、動作させることができません。

私が使用するコマンドは次のとおりです。

sed -E -f scrub.sed test.txt

そしてその scrub.sedスクリプトは次のとおりです。

:a
N
s|[[:space:]][[:space:]]| |g
s|,[[:space:]]|,|g
s|[[:space:]],|,|g
s|\n| |g
s|[[:space:]]([0-9]{5})\.|,FL,\1\n |g
$!ba

私が得るものは

Mr. John Doe,Exclusively Stuff,186 Caravelle Drive,Ponte Vedra,FL,33487n 

Zip +。(ピリオド)が置換を使用するのに最適な「区切り文字」であると考えた場合、それを見つけることができても、そこに改行を入れるように指示することはできないようです。

私がオンラインで見つけたもののほとんどは、改行を別のもので置き換えること(通常は削除)ですが、改行で置き換えることについてはあまり重要ではありません。私はこれを見つけましたが、うまくいきませんでした: `のコンマの後に改行文字を挿入する方法)、(` with sed?

行方不明のものはありますか?

更新:

Scrub.sedファイルを編集して、文字通り改行を設定しました。それでも動作しません

:a
N
s|[[:space:]][[:space:]]| |g
s|,[[:space:]]|,|g
s|[[:space:]],|,|g
s|\n| |g
s|[[:space:]]([0-9]{5})\.|,FL,\1\
|g
$!ba

私が得るものは(1行のすべて)です:

Mr. John Doe,Exclusively Stuff,186 Caravelle Drive,Ponte Vedra,FL,33487 Mrs. Jane Smith,Props and Stuff,123 Main Drive,Jacksonville,FL,336907  

予想される出力は次のとおりです。

Mr. John Doe,Exclusively Stuff,186 Caravelle Drive,Ponte Vedra,FL,33487
Mrs. Jane Smith,Props and Stuff,123 Main Drive,Jacksonville,FL,336907  
12
Allan

BSDのsedは、改行の\n表現をサポートしていません(リテラルnに変換):

$ echo "123." | sed -E 's/([[:digit:]]*)\./\1\n next line/'
123n next line

GNU sed\n表現をサポートします:

$ echo "123." | gsed -E 's/([[:digit:]]*)\./\1\nnext line/'
123
next line

代替手段は次のとおりです。

単一文字区切り文字を使用し、trを使用して新しい行に変換します。

$ echo "123." | sed -E 's/([[:digit:]]*)\./\1|next line/' | tr '|' '\n'
123
next line

または、sedスクリプトでエスケープされたリテラルの改行を使用します。

$ echo "123." | sed -E 's/([[:digit:]]*)\./\1\
next line/'
123
next line

または、awkを使用します。

$ echo "123." | awk '/^[[:digit:]]+\./{sub(/\./,"\nnext line")} 1'
123
next line

または\nをサポートするGNU sedを使用します

31
dawg

Sedで改行を取得するポータブルな方法は、バックスラッシュとそれに続くリテラル改行です。

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

ただし、sedではなくawkを使用することで、問題全体をはるかに簡単に解決できることが保証されます。

7
Ed Morton

以下は、Oracle Linux x8664で動作します。

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

1行に複数回一致させる必要がある場合は、次のようにgを最後に配置する必要があります。

$ echo 'foobarfoobaz' | sed 's/foo/foo\n/g'
foo
barfoo
baz
0
ragerdl