sed-ish oneliner 在替换中执行算术

int*_*lfx 5 bash awk sed

我有一个 form 字符串FOO_123_BAR.bazquux,其中FOOBAR是固定字符串,123是一个数字并且bazquux是自由格式的文本。

我需要对这个字符串执行文本转换:提取123bazquux,增加数字,然后将它们排列在不同的字符串中。
例如,FOO_123_BAR.bazquux? FOO=124 BAR=bazquux. (实际转换更复杂。)

自然地,我可以在一系列 sed 和 expr 调用中做到这一点,但它很难看:

shopt -s lastpipe

in=FOO_123_BAR.bazquux
echo "$in" | sed -r 's|^FOO_([0-9]+)_BAR\.(.+)$|\1 \2|' | read number text
out="FOO=$((number + 1)) BAR=$text"
Run Code Online (Sandbox Code Playgroud)

是否有更强大的文本处理工具可以在一次调用中完成这项工作?如果是,那么如何?


编辑:我很抱歉没有更清楚地说明这一点,但输入和输出的确切结构是一个例子。因此,我更喜欢使用任何分隔符或不存在分隔符的通用解决方案,而不是依赖于例如存在下划线的解决方案。

Sun*_*eep 6

使用GNU sed,您可以使用e标志将整个替换字符串作为外部命令执行。

$ s='FOO_123_BAR.bazquux'
$ echo "$s" | sed -E 's/^FOO_([0-9]+)_BAR\.(.+)$/echo FOO=$((\1 + 1)) BAR=\2/e'
FOO=124 BAR=bazquux
Run Code Online (Sandbox Code Playgroud)

为避免与 shell 元字符冲突,您需要引用未知部分:

$ s='FOO_123_BAR.$x(1)'
$ echo "$s" | sed -E 's/^FOO_([0-9]+)_BAR\.(.+)$/echo FOO=$((\1 + 1)) BAR=\2/e'
sh: 1: Syntax error: "(" unexpected

$ echo "$s" | sed -E 's/^FOO_([0-9]+)_BAR\.(.+)$/echo FOO=$((\1 + 1)) BAR=\x27\2\x27/e'
FOO=124 BAR=$x(1)
Run Code Online (Sandbox Code Playgroud)


Ed *_*ton 5

在每个 UNIX 机器上的任何 shell 中使用任何 awk 并假设您的子字符串都不包含_.

$ s='FOO_123_BAR.bazquux'
$ echo "$s" | awk -F'[_.]' '{print $1"="$2+1,$3"="$4}'
FOO=124 BAR=bazquux
Run Code Online (Sandbox Code Playgroud)