`sed` 可以用单个 `s/` 替换命令替换每行中的第五个和第七个空格吗?

`sed` 可以用单个 `s/` 替换命令替换每行中的第五个和第七个空格吗?

我可以用以下命令仅替换第五个和第七个空格:

$ echo "1 2 3 4 5 6 7 8" | sed 's/\ /x/5;s/\ /x/6'
1 2 3 4 5x6 7x8

但也许sed支持列表和范围nth 模式出现只使用一个替换s/而不是用分号分隔的两个替换?

$ echo "1 2 3 4 5 6 7 8" | sed 's/\ /x/5,7'
sed: -e expression #1, char 9: unknown option to `s'

答案1

对于带有 -like 大括号扩展的 shell csh(csh、tcsh、zsh、bash、pdksh、ksh93、、yash -o braceexpandfish,您可以执行以下操作:

$ echo 1 2 3 4 5 6 7 8 9 | sed '-es/ /x/'{7,6,5}
1 2 3 4 5x6x7x8 9 

大括号扩展将其扩展为

sed '-es/ /x/'7 '-es/ /x/'6 '-es/ /x/'5

我们向后进行,以便一次替换不会影响下一次替换。

{x..y}您可以使用from 的形式将其设置为范围zsh(现在 bash、ksh93 也支持yash -o braceexpand

$ echo 1 2 3 4 5 6 7 8 9 | sed '-es/ /x/'{7..3}
1 2 3x4x5x6x7x8 9

或两种形式的组合:

$ echo 1 2 3 4 5 6 7 8 9 | sed '-es/ /x/'{{7..3},1}
1x2 3x4x5x6x7x8 9

使用zsh,您可以将它们放入数组中:

$ substs=({7..5} 3 1)
$ echo 1 2 3 4 5 6 7 8 9 | sed '-es/ /x/'$^substs
1x2 3x4 5x6x7x8 9

并按zsh正确的相反数字顺序对它们进行排序:

$ substs=(1 8 6)
$ echo 1 2 3 4 5 6 7 8 9 | sed '-es/ /x/'${(On)^substs}
1x2 3 4 5 6x7 8x9

使用zshbash,您还可以执行以下操作:

$ substs=({7..5} 3 1)
$ echo 1 2 3 4 5 6 7 8 9 | sed "${substs[@]/#/-es: :x:}"
1x2 3x4 5x6x7x8 9

使用fish(和 GNU seq),您可以执行以下操作:

$ echo 1 2 3 4 5 6 7 8 9 | sed '-es/ /x/'(seq 6 -1 3)
1 2 3x4x5x6x7 8 9

或者:

$ set substs 5 3 1
$ echo 1 2 3 4 5 6 7 8 9 | sed '-es/ /x/'$substs
1x2 3x4 5x6 7 8 9

fish数组像在本例中rczsh -o rcexpandparam在本例中一样扩展)。


使用perl,您可以执行以下操作:

$ echo 1 2 3 4 5 6 7 8 9 | perl -pe 'BEGIN{$h{$_}=1 for (3,5..8)}
                                     my $n; s/ /$h{++$n} ? "x" : $&/ge'
1 2 3x4 5x6x7x8x9

答案2

$ echo $SHELL
/bin/bash
$ set -- 6 7 # or bash -s 6 7 (set positional parameters)
$ echo "1 2 3 4 5 6 7 8" | sed "s/ /x/$1"
1 2 3 4 5 6x7 8
$ shift # ¹
$ echo "1 2 3 4 5 6 7 8" | sed "s/ /x/$1"
1 2 3 4 5 6 7x8

1:

$help shift
shift: shift [n]
移位位置参数。

将位置参数 $N+1,$N+2 ... 重命名为 $1,$2 ... 如果未给出 N,则假定为 1。

退出状态:返回成功,除非 N 为负数或大于 $#

相关内容