使用 sed 插入换行符 (\n)

Insert newline (\n) using sed

我正在尝试将一些列表整理成格式正确的 CSV 文件以用于数据库导入。

我的起始文件看起来像这样,每一“行”应该跨越多行,如下所示

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

我创建了一个 sed 脚本来清理文件(有很多“脏”格式,例如双空格和空格 before/after 逗号)。 问题是带有句点的 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,\n |g
$!ba

我得到的是

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

如果认为 Zip+.(句号)是一个很好的“定界符”来使用替换,虽然我能找到它,但我似乎无法告诉它在那里放一个换行符。

我在网上找到的大部分内容都是关于用其他东西替换换行符(通常是删除它们),但用换行符替换的内容不多。我确实找到了这个,但没有用:How to insert newline character after comma in `),(` 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,\
|g
$!ba

我得到的是(一行中的所有内容):

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  

在 sed 中获取换行符的可移植方式是反斜杠后跟文字换行符:

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

我保证使用 awk 而不是 sed 可以更简单地解决您的整个问题。

BSD 上的 sed 不支持换行的 \n 表示(将其转换为文字 n):

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

GNU sed 确实支持 \n 表示:

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

备选方案是:

使用单个字符定界符,然后使用 tr 转换为新行:

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

或者在您的 sed 脚本中使用转义文字新行:

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

或者定义一个新行:

POSIX:

nl='
'

BASH / zsh / 其他支持 ANSI C quoting:

nl=$'\n'

然后使用 sed 加上适当的引号和转义符来插入文字 \n:

echo "123." | sed 's/\./'"\${nl}"'next line/'
123
next line

或使用awk:

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

或者使用支持\n

的GNU sed

以下适用于 Oracle Linux、x8664:

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

如果您需要它每行匹配多次,则需要在末尾放置一个 g,如:

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

在匹配后添加一行。

sed 命令可以在找到模式匹配后添加一个新行。 sed 的“a”命令告诉它在找到匹配项后添加一个新行。

sed '/unix/ a "Add a new line"' file.txt

unix is great os. unix is opensource. unix is free os.

    "Add a new line"
    
    learn operating system.
    
    unixlinux which one you choose.
    
    "Add a new line"

在匹配项前添加一行

sed 命令可以在找到模式匹配之前添加一个新行。 sed 的“i”命令告诉它在找到匹配项之前添加一个新行。

sed '/unix/ i "Add a new line"' file.txt

"Add a new line"

unix is great os. unix is opensource. unix is free os.

learn operating system.

"Add a new line"

unixlinux which one you choose.