我有一个与此类似的文件:
random_string
83: some words 45: large error report 326: send emails to certain peple
random_string
34: some words 143: job success
我想定位模式“#:”(一个数字后跟一个冒号)并在其后面的文本后面添加一个新行;所以它是这样写的:
random_string
83: some words
45: large error report
326: email certain people
random_string
34: some words
143: job success
我尝试过 sed 命令:
sed "s#'([0-9]*[0-9]:)'#a '/n'#" file.txt
sed "s#'([0-9]*[0-9]:)'#\n#g" file.txt
(我不喜欢使用斜杠作为分隔符,栅栏柱使其难以阅读)
和 awk 命令:
awk '/[0-9]*[0-9]:/ {printf "%s\n",$0}' file.txt
但两者都不起作用。我查看了此处发布的类似问题并尝试了他们的解决方案,但没有任何效果。我知道答案很可能非常相似,甚至可能与我的数字表达式中的语法有关,但我自己无法弄清楚。我对 awk 或 sed 没有偏好,但我认为它们将是我可以使用的最好工具。
帮助?
答案1
这是一个 Perl 解决方案:
$ perl -pe 's/(\d+:.*?)(?=\d+:|$)/$1\n/g' file
random_string
83: some words
45: large error report
326: send emails to certain peple
random_string
34: some words
143: job success
解释
(\d+:.*?)
:匹配一个或多个数字 (\d+
) ,后跟 a:
,然后匹配正则表达式的其余部分的最小字符串( in?
使其.*?
非贪婪,一旦找到第一个匹配就会停止)。在这里,将继续直到下面解释的部分。(?=\d+:|$)
: 这(?=foo)
被称为积极的前瞻。它会匹配,但匹配的内容不会包含在实际结果中。因此,bar(?=foo)
将匹配bar
后面跟着 的所有情况foo
。在这里,我们要查找后跟:
( )的数字字符串\d+:
或行尾 ($
)。
现在,替换运算符将用其自身和换行符替换所有出现的第一个模式,这将为您提供所需的输出。
答案2
$ cat file
random_string
83: some words 45: large error report 326: send emails to certain peple
random_string
34: some words 143: job success
您可以使用 sed:
$ sed 's/[0-9]*: [a-z ]*/&\n/g' file
输出:
random_string
83: some words
45: large error report
326: send emails to certain peple
random_string
34: some words
143: job success
答案3
awk
似乎可以解决这个问题:
$ awk '{ for( i=1; i<=NF; i++ ) { if( match( $i, ":" ) ) { printf "\n" } printf( "%s ", $i ) } }' /path/to/file
random_string
83: some words
45: large error report
326: email certain people random_string
34: some words
143: job success
答案4
将您的输入与输出进行比较,您对所需内容的描述似乎不正确。你说“我想定位模式#:(一个数字后跟一个冒号)并在后面添加一个新行”更准确的描述是:
- 将任意数量的数字之前的空格替换为换行符,后跟冒号。
- 在每个不以数字开头的非空行之前插入换行符。
- 跳过第一行输入,因为没有任何内容需要更改。
这个sed
脚本实现了这一点。它使用扩展正则表达式 ( -E
) 而不是sed
默认的基本正则表达式,以最大限度地减少所需的反斜杠转义次数并提高可读性。
$ sed -E -e '2,$ {s/ ([0-9]+:)/\n\1/g; s/^[^0-9]/\n&/}' file.txt
random_string
83: some words
45: large error report
326: send emails to certain peple
random_string
34: some words
143: job success
[0-9]+:
顺便说一句,如果或多个空白字符之前可能存在制表符而不是空格,则使用[[:space:]]+
而不是仅使用空格。例如
sed -E -e '2,$ {s/[[:space:]]+([0-9]+:)/\n\1/g; s/^[^0-9]/\n&/}' file.txt