我可以用以下命令仅替换第五个和第七个空格:
$ 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 braceexpand
)fish
,您可以执行以下操作:
$ 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
使用zsh
或bash
,您还可以执行以下操作:
$ 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
数组像在本例中rc
或zsh -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 为负数或大于 $#