regex 捕捉每行的最后一个单词

sauutmhj  于 2023-06-25  发布在  其他
关注(0)|答案(6)|浏览(130)

我有一个文件没有正确的间距,我想在美元金额和它旁边的单词之间添加一个空格,即2342.20Hello
我尝试使用sed来解决这个问题,但似乎不起作用。
我尝试了这个命令,但它似乎不工作。

sed -r 's/([0-9].*)\.([a-zA-Z].*) /\1 \2/g' /tmp/testfile2.txt

我期待的文件有:

2234.3Hello
8938.3HeyYou
1239.0New

看起来像这样:

2234.3 Hello
8938.3 HeyYou
1239.0 New

我可以使用Perlsed命令来完成上述操作。

u0njafvf

u0njafvf1#

  • 第一个解决方案:* 使用GNU awk中显示的示例,请尝试以下awk代码。
awk -v RS='[a-zA-Z]+' 'RT{sub(/^\n/,"");print $0,RT}'  Input_file

***第二种解决方案:***使用sed-E选项尝试以下操作。

sed -E 's/^([0-9]+\.[0-9]+)([^0-9]+)$/\1 \2/' Input_file
vecaoik1

vecaoik12#

您的正则表达式试图匹配.后跟[a-zA-Z]-在您的输入中不存在这样的字符串,每个.和字母之间总是有一个数字。
使用任何sed:

$ sed 's/\.[0-9]*/& /' file
2234.3 Hello
8938.3 HeyYou
1239.0 New
z4iuyo4d

z4iuyo4d3#

试试sed -E 's/([0-9]+\.[0-9]+)([a-zA-Z]+)/\1 \2/g'
正则表达式接受输入文本并查找后面跟有字母字符的十进制数字。然后,它会用十进制数字、空格和字母字符替换每个匹配项。-E选项启用扩展正则表达式,允许使用+匹配一个或多个匹配项,以及()捕获模式的特定部分,以便稍后在替换文本中使用。

djmepvbi

djmepvbi4#

使用/i进行不区分大小写的匹配

perl -pi.bak -e 's/\b\d+(?:\.\d+)?\K[A-Z]/ $&/i' file

模式匹配的地方

\b\d+(?:\.\d+)?\K[A-Z]
  • \b防止部分字匹配的字边界
  • \d+(?:\.\d+)?匹配1+位数字,可选小数部分
  • \K忘记到目前为止匹配的内容
  • [A-Z]匹配单个字符A-Z

替换的$&是一个空格,后跟匹配的内容(单个字符A-Z)

***或***如果你(如文章标题)想要捕获/匹配每行的最后一个“单词”,在这种情况下从[A-Z]开始,你可以使用锚\Z

perl -pi.bak -e 's/\b\d+(?:\.\d+)?\K[A-Z]\S*\Z/ $&/i' file
ztmd8pv5

ztmd8pv55#

这可能对你有用(GNU sed):

sed 's/\../& /' file

在小数点和一个数字后面放一个空格。

jhkqcmku

jhkqcmku6#

使用以下两个Perl一行程序之一:

perl -i.bak -pe 's{\A[\d.]+}{$& }' infile

perl -i.bak -pe 's{[^\W\d_].*}{ $&}' infile

例如,对于此输入文件:

2234Hello
2234.3Hello
2234.30Hello

这将是输出:

2234 Hello
2234.3 Hello
2234.30 Hello

Perl单行程序使用以下命令行标志:
-e:告诉Perl在行内查找代码,而不是在文件中。
-p:一次循环输入一行,默认情况下将其分配给$_。在每次循环迭代后添加print $_
-i.bak:就地编辑输入文件(覆盖输入文件)。在覆盖之前,通过在其名称后附加扩展名.bak来保存原始文件的备份副本。如果你想跳过写备份文件,只需使用-i并跳过扩展名。
给你
s{PATTERN}{REPLACEMENT}:将PATTERN更改为REPLACEMENT
\A:字符串的开头。
[\d.]+:数字或句点(.),重复一次或多次。与您的问题上下文中的数字匹配。
$&:匹配的模式。
[^\W\d_]:任意字母:[...]是字符类,^是字符类中的not运算符,\W是非字字符,\d是数字。实际上,这是一个字符类,它是一个单词字符,而不是一个数字或下划线,而是一个字母。
.*:任何重复0次或更多次的字符。

相关问题