我使用 2 行(带和不带可选后缀)进行测试(最后 2 个枚举元素,D2,E2)。
echo -e "A1,B2,C2\nA2,B2,C2,D2,E2" | sed -E 's/^(.*),(.*),(.*)((,.*)(,.*)){0,1}$/[\1],\2,\3\5\6/'
[A1],B2,C2
[A2,B2,C2],D2,E2
我想从哪里获得
[A1],B2,C2
[A2],B2,C2,D2,E2
我只想将最后两个组件设为可选,并将它们附加在末尾以防找到它们。
我尝试使用重复 {x,y} 和问号 (?),但我无法使 sed find 模式上的最后 2 个元素真正成为可选。看起来 sed 贪婪非常贪婪,因为我用 '^' 和 '$' 包装模式,而不是首先尝试不可选的模式,它只采用具有非常贪婪的第一个组件的可选模式。
注意:正则表达式是我真正需求的简化,因此通过不同的方法克服可能是徒劳的。我真的很想用 sed 和这种特殊的方法来做到这一点,因为这只是为了提高我对该工具技巧的了解
编辑:感谢您的回答,这是我的目标
sed -E 's/^([^,]*),([^,]*),([^,]*)(,[^,]*)?(,[^,]*)?$/[\1],\2,\3\4\5/'
答案1
我不确定你的 sed 构造的目的,但我可以告诉你你的错误。
在正则表达式中,您尝试将前三个字母数字组合与(.*),(.*),(.*)
.由于 sed 中的正则表达式是“贪婪的”,第一个(.*)
已经匹配三个组合,因为字母、数字和逗号与.
.要匹配单个组合,您最好匹配无逗号的字符(例如 ([^,]*),witch 匹配任意数量的无逗号字符。您的命令将如下所示:
echo -e "A1,B2,C2\nA2,B2,C2,D2,E2" | sed -E 's/^([^,]*),([^,]*),([^,]*)((,[^,]*)(,[^,]*)){0,1}$/[\1],\2,\3\5\6/'
如果它始终是三个或五个组合输入,您还可以将正则表达式“缩短”为
echo -e "A1,B2,C2\nA2,B2,C2,D2,E2" | sed -E 's/^([^,]*)(((,[^,]*){2}){1,2})$/[\1]\2/'
但这实际上取决于您的用例。
匹配^([^,]*)
第一个字母数字组合,
匹配((,[^,]*){2})
接下来的两个或四个组合,前面有一个逗号(输入示例中的,B2,C2 或,B2,C2,D2,E2)。
答案2
仍然不确定 OP 想要实现什么,但要进行非贪婪匹配,您可以使用否定字符类,在本例中为[^,]
。
echo -e "A1,B2,C2\nA2,B2,C2,D2,E2" |
sed -E 's/([^,]+)((,[^,]+){2})((,[^,]+){0,2})/[\1]\2\4/'
[A1],B2,C2
[A2],B2,C2,D2,E2
echo -e "A1,B2,C2\nA2,B2,C2,D2,E2" |
sed -E 's/([^,]+)((,[^,]+){2})((,[^,]+){0,2})/[\1]\2\5/'
[A1],B2,C2
[A2],B2,C2,E2
虽然分别捕捉每场比赛润是另一回事...
如果OP愿意给出一个更完整的例子......也许我们都可以再次循环!这项练习对我们有好处;)
答案3
$ echo -e "A1,B2,C2\nA2,B2,C2,D2,E2" | sed -e 's/[^,]*/[&]/' -e 's/[^,]*/(&)/2' -e 's/[^,]*/{&}/3'
[A1],(B2),{C2}
[A2],(B2),{C2},D2,E2
您不必尝试在一次替换中完成所有操作,而是可以利用这样一个事实:您可以通过在末尾使用数字标志来选择要处理的一场比赛(此处/2
以及/3
第二场和第三场比赛)。
为了清楚起见,上面使用的命令sed
:
sed -e 's/[^,]*/[&]/' \
-e 's/[^,]*/(&)/2' \
-e 's/[^,]*/{&}/3'