Sed regex - 包括原始匹配

Sed regex - 包括原始匹配

输入:

dsfgsdf8gfsd
2011.06.26. v
iudsfg98sdfg
sosdufgsdfg
2011.06.27. h
8xdofguiosdfg
jdasfhasd89fa
2011.06.28. k
ydsfgsdgsdg
dsfgdsfzfszgh
2011.06.29. sze
ds9fgisdfgsdfg
asdfasdfasddf
2011.06.30. cs
dsg789sdiofgsdg
dsfig89dsfgds
2011.07.01. p
sd9fg8sdgsdg
sdlfjgsd89öfgxcbv
dsglsd9gcxbv
dsflgjsdlfgfsdg
sdfsdfgdxfgxc
2011.07.02. szo
cvbdsgfsd
2011.07.03. v
dfgsdfgsd
2011.07.04. h
sdfgsdfgsdg

如何使用例如 sed 获得此输出? (或者 Perl?)

2011.06.26. v
iudsfg98sdfg
sosdufgsdfg
----------
2011.06.27. h
8xdofguiosdfg
jdasfhasd89fa
----------
2011.06.28. k
ydsfgsdgsdg
dsfgdsfzfszgh
----------
2011.06.29. sze
ds9fgisdfgsdfg
asdfasdfasddf
----------
2011.06.30. cs
dsg789sdiofgsdg
dsfig89dsfgds
----------
2011.07.01. p
sd9fg8sdgsdg
sdlfjgsd89öfgxcbv
dsglsd9gcxbv
dsflgjsdlfgfsdg
sdfsdfgdxfgxc
----------
2011.07.02. szo
cvbdsgfsd
----------
2011.07.03. v
dfgsdfgsd
----------
2011.07.04. h
sdfgsdfgsdg

所以我想交换:

2011.06.26. v

2011.06.27. h

等等:

----------
2011.06.26. v

----------
2011.06.27. h

我已经尝试过了(别笑:D):

sed "s/[0-9]\{4\}\.[0-9]\{2\}\.[0-9]\{2\}\. /WTF/g"

但我不知道如何在 sed 中匹配“h, k, sze, cs, p, szo, v”,也不知道如何将匹配的内容放入“WTF”(在... /WTF/g”)

有人有什么想法吗? :\

谢谢你!

答案1

起点是以下 sed 行:

$ echo 2011.06.26. v | sed 's/^\([0-9]\+\.[0-9]\+\.[0-9]\+\. \([hv]\|sze\)\)$/----------\n\1/'
----------
2011.06.26. v

由于 sed 使用基本的正则表达式语法(默认情况下),因此您必须对()|+字符进行转义才能获得其特殊含义(分组、替代、一个或多个)。与\1你反向参考第一场小组比赛。

答案2

我使用以下方法找到了这个解决方案sed

sed -n '/^[0-9]\{4\}\.[01][0-9]\.[0123][0-9]\./,${:a;N;$!ba;{s/\([0-9]\{4\}\.[01][0-9]\.[0123][0-9]\.\)/--------------\n\1/g;p}}'

缺点是日期必须匹配两次。也许还有另一个(更好的)解决方案。
输出与您在示例中所期望的完全一样。

答案3

换句话说,您希望----------在包含 YYYY.MM.DD 日期的每一行之前插入该行,后跟一个空格和一堆小写字母。做这件事有很多种方法。您可以使用插入命令(i):

sed -e '/^[0-9][0-9][0-9][0-9]\.[0-9][0-9]\.[0-9][0-9] [a-z][a-z]*$/ i \
----------'

或者您可以用换行符替换行开头的空字符串。

sed -e '/^[0-9][0-9][0-9][0-9]\.[0-9][0-9]\.[0-9][0-9] [a-z][a-z]*$/ s/^/----------\
'

或者您可以&在命令的替换文本中使用s来代表匹配的模式。

sed -e 's/^[0-9][0-9][0-9][0-9]\.[0-9][0-9]\.[0-9][0-9] [a-z][a-z]*$/----------\
&'

某些sed实现允许您在替换文本中写入\n而不是反斜杠换行符,但在其他实现上则\n打印\nn.

答案4

你应该使用 awk 代替

awk ' /[0-9]{4}\.[0-9]{2}\.[0-9]{2}\. / { print "---------------------\n" $0 ; continue } /^/ { print $0 } ' <"INPUTFILE" >"OUTPUTFILE"

基本上它分两步工作:

步骤1:/[0-9]{4}\.[0-9]{2}\.[0-9]{2}\. / { print "---------------------\n" $0 ; continue }

意思是:如果它匹配/4digits.2digits.2digits。 / 然后打印“---...--\n”,后跟匹配行,并在下一行循环(=“继续”)。

第2步:/^/ { print $0 }

意思是:如果我们不匹配上面的内容,那么对于所有其他行(即匹配行的开头,因此即使是空行也会匹配),只需打印该行。

相关内容