データベースのインポートのために、いくつかのリストを適切にフォーマットされた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
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を使用します
Sedで改行を取得するポータブルな方法は、バックスラッシュとそれに続くリテラル改行です。
$ echo 'foo' | sed 's/foo/foo\
bar/'
foo
bar
ただし、sedではなくawkを使用することで、問題全体をはるかに簡単に解決できることが保証されます。
以下は、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