我想弄清楚如何将字符串分解为每行字符。
即ahebhaaa
:
a
h
e
b
h
a
a
a
我试过:
$ echo ahebhaaa | sed 's/\(.\)\(.\)/\1\n\2/g'
即我的意图是使用捕获组在字符之间“插入”新行,但我得到:
a
he
bh
aa
a
我想这与贪婪/非贪婪有关,但在其中的任何地方添加 ?* 不会执行任何操作。我在这里做错了什么?
另外我发现这个:
echo ahebhaaa | sed 's/[^\n]/&\n/g'
可以完成工作。但我不明白它是如何工作的。什么是&
?工作如何[^\n]
?
答案1
捕获组
你的第一个例子很接近,但你告诉sed
你想要一次使用 2 个字符\(.\)\(.\)
,要使用捕获组来完成它,你可以像这样调整它:
$ echo ahebhaaa | sed 's/\(.\)/\1\n/g'
a
h
e
b
h
a
a
a
使用 &
至于为什么这个sed
例子有效&
。&
搜索和替换中的 是正则表达式匹配的任何字符。所以一切都是不是A \n
。
例子
$ echo "123 abc" | sed 's/[0-9]*/&&/'
123123 abc
第一个打印与模式 ( ),&
匹配的字符。第二次打印它们。[0-9]*
123
&
$ echo "123 abc" | sed 's/ab/&&&/'
123 abababc
我们正在寻找的模式是ab
.当我们行走时,字符串123 abc
sed 正在打印不匹配的字符123
。然后ab
遇到与我们正在搜索和替换的内容相匹配的字符串。然后sed
将其替换为匹配 ( ) 的内容的 3 个副本abbab
。最后sed
打印c
.
该符号[^\n]
创建了一组不是行尾字符。因此,想象一下,sed
当它沿着文本字符串行走时,ahebhaaa
它正在测试每个字符并说“这不是一个\n
”吗?如果它不是行尾字符,则sed
对此字符进行搜索和替换,并&
打印匹配的内容(即该字符)以及新行字符。然后它沿着ahebhaaa
绳子行走时重复此操作。
参考
答案2
我不明白为什么 \n 在该示例中发挥作用,因为它是单行模式空间情况,所以没有换行符。因此这应该足够了:
sed 's/./&\n/g'
答案3
Perl 中的替代方案
echo "abcdefg"|perl -nle 'print for split//'