使用 tr 替换单个新行而不是多个新行
Use tr to replace single new lines but not multiple new lines
您好,我有一个包含以下格式数据的文件:
262353824192
Motley Crue Too Fast For Love Vinyl LP Leathur Records LR123 rare 3rd pressing
http://www.ebay.co.uk/itm/Motley-Crue-Too-Fast-Love-Vinyl-LP-Leathur-Records-LR123-rare-3rd-pressing-/262353824192
301870324112
TRAFFIC Same UK 1st press vinyl LP in gatefold / booklet sleeve Island pink eye
http://www.ebay.co.uk/itm/TRAFFIC-Same-UK-1st-press-vinyl-LP-gatefold-booklet-sleeve-Island-pink-eye-/301870324112
141948187203
NOW That's What I Call Music LP'S Joblot 2-14 MINT CONDITION Vinyl
http://www.ebay.co.uk/itm/NOW-Thats-Call-Music-LPS-Joblot-2-14-MINT-CONDITION-Vinyl-/141948187203
我想用管道替换单个新行,但让双新行保持原样。我试过:
tr '\n' '|' < text.txt
但这会将所有新行替换为 |因此,单独的产品不再位于不同的生产线上。我基本上想要一个 |产品编号、标题和 url 之间的分隔符,但每个单独的产品在不同的行上。我怎样才能做到这一点?
您可以使用 awk
来做到这一点:
awk ' /^$/ { print; } /./ { printf("%s|", [=10=]); } END {print '\n'}' text.txt
这将找到任何空白行并按原样打印。如果它鳍
ds 行上的任何值,它将使用 printf 并在其后粘贴一个管道。在处理结束时,它会打印一个换行符来结束。
这已经得到了部分回答HERE,但还没有完全回答。
我会添加一个额外的转换来将双换行符更改为某个字符(在本例中为散列),然后在更改后用换行符替换散列(或者两个,如果你想回到原来的格式)单个换行符是管道。
sed -e ':a' -e 'N' -e '$!ba' -e 's/\n\n/#/g' -e 's/\n/|/g' -e 's/#/\n/g'
这给出了输出:
262353824192|Motley Crue Too Fast For Love Vinyl LP Leathur Records LR123 rare 3rd pressing|http://www.ebay.co.uk/itm/Motley-Crue-Too-Fast-Love-Vinyl-LP-Leathur-Records-LR123-rare-3rd-pressing-/262353824192
301870324112|TRAFFIC Same UK 1st press vinyl LP in gatefold / booklet sleeve Island pink eye|http://www.ebay.co.uk/itm/TRAFFIC-Same-UK-1st-press-vinyl-LP-gatefold-booklet-sleeve-Island-pink-eye-/301870324112
141948187203|NOW That's What I Call Music LP'S Joblot 2-14 MINT CONDITION Vinyl|http://www.ebay.co.uk/itm/NOW-Thats-Call-Music-LPS-Joblot-2-14-MINT-CONDITION-Vinyl-/141948187203
awk
救援!
awk -F'\n' -v RS= -v OFS='|' '{=;printf "%s", [=10=] RT}' file
这保留了段落之间的间距,与原始文件中一样为 3 行。
只需使用 sed:
sergey@x50n:~> cat in.txt | tr '\n' '|' | sed -e 's/||\+/\n\n/g; s/|$/\n/'
262353824192|Motley Crue Too Fast For Love Vinyl LP Leathur Records LR123 rare 3rd pressing|http://www.ebay.co.uk/itm/Motley-Crue-Too-Fast-Love-Vinyl-LP-Leathur-Records-LR123-rare-3rd-pressing-/262353824192
301870324112|TRAFFIC Same UK 1st press vinyl LP in gatefold / booklet sleeve Island pink eye|http://www.ebay.co.uk/itm/TRAFFIC-Same-UK-1st-press-vinyl-LP-gatefold-booklet-sleeve-Island-pink-eye-/301870324112
141948187203|NOW That's What I Call Music LP'S Joblot 2-14 MINT CONDITION Vinyl|http://www.ebay.co.uk/itm/NOW-Thats-Call-Music-LPS-Joblot-2-14-MINT-CONDITION-Vinyl-/141948187203
首先,我们使用 tr
将所有换行符替换为管道,如您的示例所示。
然后 sed
命令中的第一个表达式(即 s/||\+/\n\n/g;
)用两个换行符替换所有出现的多个管道。如果您不希望输出行之间有空行,您也可以将它们替换为一行。 sed
的第二个表达式用换行符替换尾部管道以产生更易读的输出(或文件末尾的更多 "conventional" 空行)。
另请注意,sed 正则表达式中的 \+
是 GNU 扩展。因此,如果您使用 sed
(FreeBSD、AIX 等)的非 GNU 实现,请使用标准语法:|||*
而不是 ||\+
.
我用 awk 对你的问题做了一个非常具体的解决方案(具体是因为它假设你在记录组之间总是有相同数量的新行)。
awk 'BEGIN {RS="\n\n\n"; FS="\n"; OFS="|"} {print ,,}' < text.txt
设置记录分隔符为3个换行符,字段分隔符为1个换行符,输出字段分隔符为管道符。然后对于每条记录(每个块由 3 个换行符分隔),它打印前 3 个字段(由一个换行符分隔),并在输出中用竖线
分隔它们
使用 tr 和一点 sed:
tr "\n" "|" < text.txt | sed 's/||\+/\n/g'
您好,我有一个包含以下格式数据的文件:
262353824192
Motley Crue Too Fast For Love Vinyl LP Leathur Records LR123 rare 3rd pressing
http://www.ebay.co.uk/itm/Motley-Crue-Too-Fast-Love-Vinyl-LP-Leathur-Records-LR123-rare-3rd-pressing-/262353824192
301870324112
TRAFFIC Same UK 1st press vinyl LP in gatefold / booklet sleeve Island pink eye
http://www.ebay.co.uk/itm/TRAFFIC-Same-UK-1st-press-vinyl-LP-gatefold-booklet-sleeve-Island-pink-eye-/301870324112
141948187203
NOW That's What I Call Music LP'S Joblot 2-14 MINT CONDITION Vinyl
http://www.ebay.co.uk/itm/NOW-Thats-Call-Music-LPS-Joblot-2-14-MINT-CONDITION-Vinyl-/141948187203
我想用管道替换单个新行,但让双新行保持原样。我试过:
tr '\n' '|' < text.txt
但这会将所有新行替换为 |因此,单独的产品不再位于不同的生产线上。我基本上想要一个 |产品编号、标题和 url 之间的分隔符,但每个单独的产品在不同的行上。我怎样才能做到这一点?
您可以使用 awk
来做到这一点:
awk ' /^$/ { print; } /./ { printf("%s|", [=10=]); } END {print '\n'}' text.txt
这将找到任何空白行并按原样打印。如果它鳍 ds 行上的任何值,它将使用 printf 并在其后粘贴一个管道。在处理结束时,它会打印一个换行符来结束。
这已经得到了部分回答HERE,但还没有完全回答。
我会添加一个额外的转换来将双换行符更改为某个字符(在本例中为散列),然后在更改后用换行符替换散列(或者两个,如果你想回到原来的格式)单个换行符是管道。
sed -e ':a' -e 'N' -e '$!ba' -e 's/\n\n/#/g' -e 's/\n/|/g' -e 's/#/\n/g'
这给出了输出:
262353824192|Motley Crue Too Fast For Love Vinyl LP Leathur Records LR123 rare 3rd pressing|http://www.ebay.co.uk/itm/Motley-Crue-Too-Fast-Love-Vinyl-LP-Leathur-Records-LR123-rare-3rd-pressing-/262353824192
301870324112|TRAFFIC Same UK 1st press vinyl LP in gatefold / booklet sleeve Island pink eye|http://www.ebay.co.uk/itm/TRAFFIC-Same-UK-1st-press-vinyl-LP-gatefold-booklet-sleeve-Island-pink-eye-/301870324112
141948187203|NOW That's What I Call Music LP'S Joblot 2-14 MINT CONDITION Vinyl|http://www.ebay.co.uk/itm/NOW-Thats-Call-Music-LPS-Joblot-2-14-MINT-CONDITION-Vinyl-/141948187203
awk
救援!
awk -F'\n' -v RS= -v OFS='|' '{=;printf "%s", [=10=] RT}' file
这保留了段落之间的间距,与原始文件中一样为 3 行。
只需使用 sed:
sergey@x50n:~> cat in.txt | tr '\n' '|' | sed -e 's/||\+/\n\n/g; s/|$/\n/'
262353824192|Motley Crue Too Fast For Love Vinyl LP Leathur Records LR123 rare 3rd pressing|http://www.ebay.co.uk/itm/Motley-Crue-Too-Fast-Love-Vinyl-LP-Leathur-Records-LR123-rare-3rd-pressing-/262353824192
301870324112|TRAFFIC Same UK 1st press vinyl LP in gatefold / booklet sleeve Island pink eye|http://www.ebay.co.uk/itm/TRAFFIC-Same-UK-1st-press-vinyl-LP-gatefold-booklet-sleeve-Island-pink-eye-/301870324112
141948187203|NOW That's What I Call Music LP'S Joblot 2-14 MINT CONDITION Vinyl|http://www.ebay.co.uk/itm/NOW-Thats-Call-Music-LPS-Joblot-2-14-MINT-CONDITION-Vinyl-/141948187203
首先,我们使用 tr
将所有换行符替换为管道,如您的示例所示。
然后 sed
命令中的第一个表达式(即 s/||\+/\n\n/g;
)用两个换行符替换所有出现的多个管道。如果您不希望输出行之间有空行,您也可以将它们替换为一行。 sed
的第二个表达式用换行符替换尾部管道以产生更易读的输出(或文件末尾的更多 "conventional" 空行)。
另请注意,sed 正则表达式中的 \+
是 GNU 扩展。因此,如果您使用 sed
(FreeBSD、AIX 等)的非 GNU 实现,请使用标准语法:|||*
而不是 ||\+
.
我用 awk 对你的问题做了一个非常具体的解决方案(具体是因为它假设你在记录组之间总是有相同数量的新行)。
awk 'BEGIN {RS="\n\n\n"; FS="\n"; OFS="|"} {print ,,}' < text.txt
设置记录分隔符为3个换行符,字段分隔符为1个换行符,输出字段分隔符为管道符。然后对于每条记录(每个块由 3 个换行符分隔),它打印前 3 个字段(由一个换行符分隔),并在输出中用竖线
分隔它们使用 tr 和一点 sed:
tr "\n" "|" < text.txt | sed 's/||\+/\n/g'