使用 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.
我正在尝试将一些列表整理成格式正确的 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
以下适用于 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.