我有一个包含很长字符串的文件,我想用 Ns 替换它的子字符串。例子:
测试
ABCDABCDABCD
我想用 awk 命令和 sed 将其子字符串替换为所有字母 N,即索引 5 到 8 的所有字符,因此字母 N 的总长度为 4。
输出
ABCDNNNNABCD
我尝试过这样的事情:
awk '{ v=substr($0,5,4); sed -i "s/$v/N/g";print substr($0,1,4)""v""substr($0,9,12)}' test
然而,这个命令似乎给出了这个输出:
ABCDABCDABC
并且没有进行替换
我想在代码中包含从哪里开始替换的索引号(例如,这里是 5)和替换的长度号(这里是 4),所以我可以修改这些数字,以防万一我想从另一个位置开始并进行不同长度的替换,因为实际上,我有一个包含数千个字母的字符串,并且我想替换数百个字符,因此模式替换在我的情况下不起作用
答案1
使用 GNU awk,你可以做
gawk -v start=5 -v end=8 '{
mid = substr($0, start, end-start+1)
print substr($0, 1, start-1) gensub(/./, "N", "g", mid) substr($0, end+1)
}' file
或者用 perl
perl -spe 'substr($_, $start-1, $end-$start+1) =~ s/./N/g' -- -start=5 -end=8 file
对于这两种解决方案,我们都使用命令行选项将开始值和结束值传递给程序。这使得在 shell 脚本中更改值变得容易。如果您还需要使替换角色 N 动态化,那么如何做应该是非常明显的。
答案2
如果您有 GNU awk (gawk),您可以设置FIELDWIDTHS
根据字符位置将行拆分为字段。这对于 gawk 版本 >= 4.2 中的情况特别方便,它支持“通配符”尾随字段宽度。然后,您可以使用以下命令替换第二个字段中的字符gsub
:
echo ABCDABCDABCD | ./gawk -v i=5 -v n=4 '
BEGIN {FIELDWIDTHS = sprintf("%d %d *", i-1, n)}
{gsub(/./,"N",$2)} 1
' OFS=""
ABCDNNNNABCD
在旧版本的 gawk 中,您可以*
通过为尾随字段选择适当大的最大大小来模拟:
echo ABCDABCDABCD | gawk -v i=5 -v n=4 '
BEGIN {FIELDWIDTHS = sprintf("%d %d 65536", i-1, n)}
{gsub(/./,"N",$2)} 1
' OFS=""
ABCDNNNNABCD
看
答案3
您可以尝试使用以下命令
echo "ABCDABCDABCD"| sed "s/ABCD/NNNN/2"
输出
ABCDNNNNABCD
答案4
您可以通过使用以下方法来完成此操作,如 POSIX 或 GNU seds 所示
使用 sed 编辑器:
$ L=5 R=8
$ sed -e '
s/./\n/'"$L"';s//\n/'"$R"';ta
:a;s/\n\n/NN/;t
s/\n./N\n/;ta
' ./test
ABCDNNNNABCD
使用 Perl:
perl -lspe '
my $c = $idxr - (pos()=$idxl-1);
s/\G.{$c}/"N"x$c/e;
' -- -idxl=5 -idxr=8 ./test
ABCDNNNNABCD