使用bash

使用bash

我做了一些研究,我可以用“.”分割字符串但我唯一想要替换的是第三个“.”,并且版本号实际上是可变的,那么我该如何进行替换/拆分?

version: 1.8.0.110

但我想要的是这样的输出:

version: 1.8.0-110

答案1

用于sed例如:

$ echo 'version: 1.8.0.110' | sed 's/\./-/3'
version: 1.8.0-110

解释:

sed s/search/replace/x搜索一个字符串并将其替换为另一个字符串。x确定要替换的事件 - 这里是第三个。通常g用于x表示所有发生的情况。

这里我们希望替换点,但这是正则表达式中该术语所期望的.特殊字符。因此,我们反斜杠to来指定文字。sedsearch.\..

由于我们在参数中使用特殊字符sed(此处为反斜杠\),因此我们需要将整个参数放在单引号中''。许多人总是在此处使用引号,以免在使用 shell 特有的字符(例如空格)时遇到问题。

答案2

使用bash

您不需要外部程序来执行此操作,特别是因为您似乎想要替换最后的带破折号的句号。 Bash 本身可以处理字符串操作。

假设你有

vers='version: 1.8.0.110'

答案很简单:

$ echo ${vers%.*}-${vers##*.}
1.8.0-110

% 表示删除右侧匹配的最短字符串。 ## 表示删除左侧匹配的最长字符串。

如果超过三个周期怎么办?

如果你真的想替换第三个句点,而不是我上面假设的最后一个句点,那么在 bash 中它会变得有点棘手,但它仍然是可能的。例如,如果vers='version: 1.8.0.110.hut.hut.hut.hike!',您可以找到第三个句点之后的所有内容并使用它来截断字符串:

$ end=${vers#*.*.*.}
$ start=${vers%$end}
$ echo ${start%.}-$end
version: 1.8.0-110.hut.hut.hut.hike!

另一种方法:使用 IFS 将字符串拆分为 bash 数组

虽然这对于这个问题来说有点过分了,但有时将字符串拆分为多个组件并将它们加载到数组中是有用的。

IFS=. read -a foo <<<'version: 1.8.0.110.hut.hut.hut.hike!'

您可以迭代数组$foo并选择何时打印内容。例如,

echo -n $foo
for ((i=1; i<${foo[@]}; i++)); do 
  [[ i -eq 3 ]] && echo -n - || echo -n .
  echo -n ${foo[i]};
done
echo

答案3

在这种情况下,第三个也是最后一个。如果您可以放心地假设您总是需要更改最后一个.,您可以这样做:

$ echo 'version: 1.8.0.110' | sed 's/\.\([^.]*\)$/-\1/'
version: 1.8.0-110

或者,如果您sed支持-E(大多数支持):

$ echo 'version: 1.8.0.110' | sed -E 's/\.([^.]*)$/-\1/'
version: 1.8.0-110

这将查找 a .,然后查找 0 个或多个非.字符 ( [^.]),直到行尾 ( $)。因为[^.]*位于括号 ( ) 中,所以它被“捕获”并且可以在替换运算符的右侧\( \)引用。\1因此,这将用 a 和那些字符替换其后面的.和非字符。-.-


如果这一定是第三次而不是最后一次@Ned64 已经给出了最简单的方法,但作为替代方案,您可以这样做:

$ echo 'version: 1.8.0.110' | perl -pe 's/(([^.]+\.){2}[^.]+)\./$1-/'
version: 1.8.0-110

相关内容