Regex 正则表达式匹配字符串的组件并重新定位

Regex 正则表达式匹配字符串的组件并重新定位,regex,sed,Regex,Sed,我有许多字符串要搜索并重新格式化。我在MacOS 10.14.6上使用gsed v4.7来实现这一点。我的目标是将字符串分解为反向引用,以便可以重新格式化 这里有一个候选人被转化的例子: vib.h.p.f2.synt 4 vib.h.p.g#2.synt 7 vib.h.p.a#3.synt 8 vib.h.p.a#3.synt 8 将成为 vib.h.p.a#3.8.synt …请注意,数字8从末端移除,并拼接在#3和synt之间,以点分隔 以下是候选人名单: vib.h.p.f2.syn

我有许多字符串要搜索并重新格式化。我在MacOS 10.14.6上使用gsed v4.7来实现这一点。我的目标是将字符串分解为反向引用,以便可以重新格式化

这里有一个候选人被转化的例子:

vib.h.p.f2.synt 4
vib.h.p.g#2.synt 7
vib.h.p.a#3.synt 8
vib.h.p.a#3.synt 8

将成为

vib.h.p.a#3.8.synt

…请注意,数字
8
从末端移除,并拼接在
#3
synt
之间,以点分隔

以下是候选人名单:

vib.h.p.f2.synt 4
vib.h.p.g#2.synt 7
vib.h.p.a#3.synt 8
如果您查看这个示例字符串的组件,可以相当容易地将它们分解为组

我找不到一种方法将其形式化为符合
gsed
需要的表达式

以下是我尝试过的:

vib.h.p.f2.synt 4
vib.h.p.g#2.synt 7
vib.h.p.a#3.synt 8
gsed-r's/(vib\.+)\(.+)\s(\d)/\1.\3.\2/g'myfile.txt

gsed-r's/vib\.(.*)\.(.*)\s(\d)/vib.\1\3\2/g'myfile.txt

gsed-r's/(vib\..*)\(.*)s(\d)/\1.\3.\2/g'myfile.txt

我知道我错过了一些关键的东西,可能是一种消极的展望? 我的直觉告诉我,我已经接近一个解决方案,尽管我已经放弃了今晚

编辑12/16/19-下面@Wiktor的回答建议使用如下命令

gsed-r的/(vib.+)\(.+)[[:blank:]+([0-9]+)/\1.\3.\2/g'myfile.txt

这不会在我的机器上打印所需的转换。相反,它打印原始文本而不进行任何替换,因为它无法成功匹配。我无法在另一台机器上测试,因此我不知道这是否是正确答案,但我已经尝试了所有建议的变体,包括使用
[[:space:]
[[:blank:]]
[0-9]
,以及
+
而不是
*
。如果有人能帮忙,我将不胜感激。

您可以使用

gsed -r 's/(vib.+)\.(.+)[[:blank:]]+([0-9]+)/\1.\3.\2/g' myfile.txt
要点:

  • \.+
    匹配一个或多个点,而不是任何一个或多个字符,因此需要删除反斜杠
  • \d
    \s
    的可移植性不强,因此将
    \d
    替换为
    [0-9]
    ,并将
    \s
    替换为空格或
    [:blank:]
  • 如果第3组中的数字多于一个,则可能会交换部分数字,添加
    +
    (由于使用
    -r
    选项,POSIX ERE语法将
    +
    视为一个或多个出现量词)

我想我终于找到了我希望的替代品

gsed-r's/(vib.\w.)(\w+。(\w[0-9]|\w\#[0-9])(\w+)\s([0-9])/\1\2\5.\4/g'myfile.txt

这适合我的需要,但可能有一种更优雅的方式。 我将包含我用作测试的文本,以防有人能想出更好的解决方案。

使用此正则表达式:

([.#0-9a-zA-Z]+\)(\S*)\S+([0-9]+)

并替换为
$1$3.$2


这对我来说似乎很简单。我错过了什么

echo "vib.h.p.f2.synt 4" | sed -E 's/(.*[0-9]+)(\.[^0-9]+) ([0-9]+)$/\1.\3\2/g'
vib.h.p.f2.4.synt
请注意,这是通过macOS中的stock sed完成的,其中
-E
将您带到这里

还请注意,这可以使用字符类来完成,如下所示:

... sed -E 's/(.*[[:digit:]]+)(\.[^[:digit:]]+) ([[:digit:]]+)$/\1.\3\2/g'

但如果您需要使用字符类,您可能已经知道了这一点。:)

谢谢,虽然它似乎不起作用。使用OSX 10.14.6(18G1012)上的
gsed
v4.7@jml请注意,s命令应使用单引号。在OSX上,您可以只使用sed-E的/(vib.+)\(.+)[[:blank:]+([0-9]+)/\1.\3.\2/g'myfile.txt是的,我包括了单引号。
-E
-r
选项均不适用于此处的
gsed
sed
。我还尝试了包括
\s
\d
[:space:]
@jml的变体。你说的“工作”是什么意思?您是否将结果通过管道传输到文件?还是使用
-i
标志将结果保存在文件中<代码>sed-E的/(vib.+)\(.+)[[:blank:]+([0-9]+)/\1.\3.\2/g'myfile.txt>output.txt。请参阅。@jml由于总体思路是正确的,您可以探索以下内容:1)用空格替换
[[:blank:][]
,或
[]
,2)尝试使用一些简化模式的POSIX BRE变体:
sed's/\(vib.*\)\(.*\)[[]*\([0-9][0-9]*\)/\1.\3.\2/g'myfile.txt
您可以共享gsed的版本吗?请展开“这不会执行所需的…”-您得到的输出是什么?您列出的尝试不包括引号-如何运行它们?@dash-o-根据您要求的信息进行了修改。这不包括上面列出的文件中列举的所有情况(请参见问题)@jml,您能更具体一点吗?OP提供了一个示例,此解决方案适用于该示例。正如我问的,我错过了什么?