如何使用sed从第n次出现到第n次出现非常长的字符串

时间:2017-11-18 10:31:47

标签: string bash shell sed

我有一个非常长的字符串,超过2000次出现,看起来像这样:

输入:

1a2a3a4a5a6a7a8absoad8ryaa90thneas ...以及

我希望在字符串的第3到第450次出现时替换多次出现:

1a2a3A4A5A6A7A8AbsoAd8ryAA90thneAs ...以及

我将“a”替换为“A”,它从第3次更换为结束,但我只想从第3次替换为第450次,这是我的旧脚本:

echo "1a2a3a4a5a6a7a8absoad8ryaa90thneas..." | sed 's/a/A/3g';

有人帮助我吗?或者还有其他方法吗?谢谢!

4 个答案:

答案 0 :(得分:1)

将字符串保存到变量,然后使用大括号扩展来定位要使用bash全局替换替换的字符串中的位置字符。请考虑以下示例:

## Our sample string. ##
string="abcde01234

## New, changed string. ##
echo "${string//${string:0:1}/${string:5:1}}"

在此示例中,当作为bash脚本运行时,$string的第一个字符将替换为$string的第六个字符。知道了这个小技巧,我相信你会找到一种方法来做你需要的而不必使用sed。或者,您可以在sed中使用大括号扩展。

## Our sample string ##
string="abcde01234"

## New, changed, string. Output is the same as above example. ##
sed -e "s/${string:0:1}/${string:5:1}/g" <(echo "$string")

这应该足以让你朝着正确的方向前进,找到满足你需求的最佳方式。

答案 1 :(得分:0)

选择一个你确定不在输入中的字符..例如ASCII NUL字符,然后就可以了

$ # replacing 3rd to 4th
$ echo "a1a23a5a62a34a235a" | sed 's/a/\x0/3g; s/\x0/a/3g; s/\x0/A/g'
a1a23A5A62a34a235a
$ # replacing 3rd to 5th
$ echo "a1a23a5a62a34a235a" | sed 's/a/\x0/3g; s/\x0/a/4g; s/\x0/A/g'
a1a23A5A62A34a235a
$ # replacing 3rd to 6th
$ echo "a1a23a5a62a34a235a" | sed 's/a/\x0/3g; s/\x0/a/5g; s/\x0/A/g'
a1a23A5A62A34A235a

答案 2 :(得分:0)

这可能适合你(GNU sed):

sed -r 's/a/\n&/3;s//&\n/450;h;y/a/A/;G;s/.*\n(.*)\n.*\n(.*)\n.*\n/\2\1/' file

使用标记将字符串拆分为碎片(换行符不能出现在新的字符串中,因为它是sed如何拆分文件),制作副本然后进行更改,附加副本并重新排列碎片。

或者使用GNU sed global replace flag:

sed 's/a/\n/451g;s//A/3g;s/\n/a/g' file

答案 3 :(得分:0)

sed -E ':again ; s/^(.{4,449})a/\1A/ ; t again' file

您可以使用t命令branch to label。当替换发生时,这是条件转到 :label。因此,对于字符范围[x:y],regexp .*{x-1,y-1}a将首次匹配贪婪,但我们会循环直到没有更多匹配。