使用regex替换bash脚本中的字符串,用于linux和AIX

时间:2014-08-06 15:35:20

标签: regex linux bash aix

我有一个bash脚本,我在linux和AIX服务器上复制和运行 这个脚本得到一个代表文件名的“name”参数,我需要通过regex操作这个名字(目的是无关紧要,很难解释)。
从name参数我需要从头开始,直到第一个“ - ”字符后跟一个数字,然后用最后一个“。”连接它。直到字符串结尾的字符。

例如:

name: abcd-efg-1.23.4567-8.jar will become: abcd-efg.jar
name: abc123-abc3.jar          will remain: abc123-abc3.jar
name: abc-890.jar              will become: abc.jar

我尝试了几种变体:

name=$1
regExpr="^(.*?)-\d.*\.(.*?)$/g"
echo $name 
echo $(printf ${name} | sed -e $regExpr)

此外,我无法使用sed -r(在某些示例中看到),因为AIX sed不支持-r标志。

最后一行是问题;我想我需要以某种方式使用$ 1 + $ 2占位符,但我似乎无法正确使用它。

如何更改我的正则表达式以使其达到我想要的效果?

4 个答案:

答案 0 :(得分:5)

鉴于文件:

abcd-efg-1.23.4567-8.jar
abc123-abc3.jar
abc-890.jar

这是一种更改名称的方法:

$ sed 's/\(.\?\)-[0-9].*\(\.[a-z]*\)$/\1\2/' file
abcd-efg.jar
abc123-abc3.jar
abc.jar

相当于(如果可以使用-r):

$ sed -r 's/(.?)-[0-9].*(\.[a-z]*)$/\1\2/' file
abcd-efg.jar
abc123-abc3.jar
abc.jar
  • 它可以获得- + digit和"商店"在\1
  • 来自上一个. + letters和"商店"在\2
  • 最后它将这些块打印回来。

请注意,也可以使用basename内置或类似“" $ {line ## *。}"”来获取扩展名。

答案 1 :(得分:1)

在sed中,您可以简单地使用以下内容。

#!/bin/sh
STRING=$( cat <<EOF
abcd-efg-1.23.4567-8.jar
abc123-abc3.jar
abc-890.jar
EOF
)
echo "$STRING" | sed 's/-[0-9].*\(\.[^.]\+\)$/\1/'
# abcd-efg.jar
# abc123-abc3.jar
# abc.jar

这匹配一个连字符后跟一个数字以及之后的所有内容并替换为文件扩展名。

或者你可以考虑使用Perl单线:

echo "$STRING" | perl -pe 's/-\d.*(?=\.[^.]+$)//'
# abcd-efg.jar
# abc123-abc3.jar
# abc.jar

答案 2 :(得分:1)

你可以用这个:

perl -F'(-(?:\d)|\.)' -ane 'print "$F[0].$F[$#F]"'

它将输入分为任何-后跟数字或任何.。然后打印第一个字段,后跟一个点,然后是最后一个字段。

测试出来:

$ cat file
abcd-efg-1.23.4567-8.jar
abc123-abc3.jar
abc-890.jar
$ perl -F'(-(?:\d)|\.)' -ane 'print "$F[0].$F[$#F]"' file
abcd-efg.jar
abc123-abc3.jar
abc.jar

答案 3 :(得分:0)

当成功进行正则表达式匹配时,perl将捕获括号(..)中匹配的任何内容,如$ 1,$ 2等。

$ perl -e 'my $arg = $ARGV[0]; $arg =~ /^(.*?)-\d.*\.(.*?)$/; print "$1.$2\n"; ' abc-890.jar
abc.jar