用awk或sedreplacestring中的字符

鉴于下面的string,如何使用awksed获取第14位和第15位来replace第6位和第7位。

xxxxx02xxxxxx89xx xxxxx22xxxxxx33xx 

产量

 xxxxx89xxxxxx89xx xxxxx33xxxxxx33xx 

我在这里是新手,对我的问题感到抱歉。

sed命令很简单,但很难理解:

 sed 's/\(.....\)..\(......\)\(..\)/\1\3\2\3/' 

Gnu awk可能有更好的维护方案(但不包括awk的其他类型,但是请参阅下面的内容):

 gawk -v FIELDWIDTHS="5 2 6 2 999" -v OFS='' '{$2=$4;print}' 

FIELDWIDTHS变量定义了5个固定宽度的字段:前5个字符,后两个字符(位置6和7); 接下来的六个字符(8到13); 接下来的两个字符(14和15); 和下一个(最多)999个字符,这应该是行的其余部分。 (如果你有更长的线,必要时增加)。 设置OFS为空常常对固定长度的字段有用; 它可以防止awk在输出中的字段之间插入空格。

FIELDWIDTHS是一个GNU awk扩展。 但是,在Posix awk重新实现是很容易的。 这是一个简单的实现:

 function fieldwidth_set( i) { if (PROCINFO["FS"]) FIELDWIDTHS = FIELDWIDTHS; else if (length(FIELDWIDTHS)) { _FW_NF = split(FIELDWIDTHS, _FW_ARRAY); for (i in _FW_ARRAY) { if (_FW_ARRAY[i] !~ /^[0-9]+$/) { printf "Illegal value '%s' in FIELDWIDTHS\n", _FW_ARRAY[i] >>"/dev/stderr"; exit 1; } _FW_ARRAY[i]+=0; } } else _FW_NF = 0; } function set_fieldwidth(fw) { FIELDWIDTHS=fw; fieldwidth_set(); } function fw_( a,i,k) { if (_FW_NF) { a = $0; $0 = ""; k=1; for (i=1; i<=_FW_NF; ++i) { $i = substr(a, k, _FW_ARRAY[i]); k+=_FW_ARRAY[i]; } } } BEGIN{set_fieldwidth()} {fw_()} 

据我所知,只有Gnu awk可以让您在awk命令行上混合程序文件和程序文本。 Posix需要-f program-file选项,这个选项可以重复,但是不需要像Gnu awk实现的-e program-text选项。 因此,如果你想用命令行awk程序来使用上面的代码片段,你需要这样做:

 awk -v FIELDWIDTHS="5 2 6 2 999" -v OFS= -f fw.awk -f <(echo '{$2=$4;print}') 

(假设您将fieldwidth片段放入fw.awk 。)

为了提高效率, fw.awk坚持告诉你已经通过调用fieldwidth_set()改变了FIELDWIDTHS 。 或者,您可以使用set_fieldwidth("....")FIELDWIDTHS设置为新值。 它将与GNU awk以及其他awk实现一起工作; 它可以让GNU awk完成繁重的工作。

你可以尝试下面的sed命令,

 $ echo 'xxxxx03xxxxxx75xx' | sed -r 's/^(.{5})(..)(.{6})../\1\2\3\2/g' xxxxx03xxxxxx03xx $ echo 'xxxxx03xxxxxx75xx' | sed 's/^\(.\{5\}\)\(..\)\(.\{6\}\)../\1\2\3\2/g' xxxxx03xxxxxx03xx 

它用第6和第7位的数字替换第14和第15位数字。

 $ echo 'xxxxx03xxxxxx75xx' | sed -r 's/^(.{5})..(.{6})(..)/\1\3\2\3/g' xxxxx75xxxxxx75xx $ echo 'xxxxx03xxxxxx75xx' | sed 's/^\(.\{5\}\)..\(.\{6\}\)\(..\)/\1\3\2\3/g' xxxxx75xxxxxx75xx 

它用第14和第15位的数字替换第6和第7位数字。

这应该遵循您的要求,并与所有awk工作:

 awk '{$6=$14;$7=$15}1' FS= OFS= file xxxxx89xxxxxx89xx xxxxx33xxxxxx33xx 

它会改变位置6的数字14和1中的一个与整数15

如果FS=""不起作用,试试这个:

 awk '{n=split($0,a,"");a[6]=a[14];a[7]=a[15];for (i=1;i<=n;i++) printf "%s",a[i];print ""}' input 

根据请求之一的评论:
It works, thanks! How about if I want to replace 14th and 15th digit by 6th and 7th digit? – Vision111

 awk '{$14=$6;$15=$7}1' FS= OFS= file 

这将无GNU awk GAWK

 awk 'sub(/[0-9]+/,substr($0,14,2))' file 

或更长,但更通用

 awk '{print substr($0,0,5) substr($0,14,2) substr($0,8)}' file 

结果:

 xxxxx89xxxxxx89xx xxxxx33xxxxxx33xx