如何使用sed或awk替换包含某个子串的行的第k个出现的最后n个字符?

时间:2017-09-11 11:35:15

标签: bash awk sed

假设我有一个类似于以下格式的文件:

\\ Random other lines \\
...
27861NA+    NA+89122  13.480  11.554  10.082
27862NA+    NA+89123   2.166   5.896  10.108
27863NA+    NA+89124   8.289   6.843   3.090
27864NA+    NA+89125  12.972   5.936   4.498
27865CL-    CL-89126  13.914   2.125  12.915
27866CL-    CL-89127  12.050  13.907   3.559
...
\\ Random other lines \\

我正在尝试找到一种方法,用我准备好的字符串替换每行的最后24个字符,对于包含字符串" NA +&#34的文件中的前3行实例;

例如,我的输出最好是:

\\ Random other lines \\
...
27861NA+    NA+89122  my first string  hello
27862NA+    NA+89123  my second string foo  
27863NA+    NA+89124  my final string bar $$
27864NA+    NA+89125  12.972   5.936   4.498
27865CL-    CL-89126  13.914   2.125  12.915
27866CL-    CL-89127  12.050  13.907   3.559
...
\\ Random other lines \\

到目前为止,我找到了一个sed命令,可以删除文件中每个行的最后24个字符:

sed 's/.\{24\}$//' myfile.txt

还有一个awk命令,它将返回包含所需子字符串的第k行:

awk '/NA+/{i++}i==1' myfile.txt

有没有人知道如何替换我文件的第1行,第2行和第3行中的最后24个字符,每行包含一个子字符串?

3 个答案:

答案 0 :(得分:2)

使用单个 awk

awk -v str="my string" '!f && /NA\+/{ f=1; n=NR+3 }n && n>NR{ $4=$5=""; $3=str }1' myfile.txt

答案 1 :(得分:0)

string="my first string hello"
awk -v string="$string" '{ if ( $0 ~ "NA" ) {cnt++} if (cnt < 4 ) { print substr($0,1,length($0)-23)string } else { print }}' NA

使用awk,设置一个字符串并使用-v将其传递给awk。搜索包含NA的字符串和增量变量cnt。当cnt小于4时,打印除最后23个字符之外的所有内容,并添加传递给结尾的字符串。否则打印线。

答案 2 :(得分:0)

这可能适合你(GNU sed):

sed '/NA+/{x;s/\n/&/3;x;ta;H;s/.\{24\}$/some string/;b;:a;n;ba}' file

这使用保留空间(HS)来保持脚本看到所需字符串(NA+)的行数。一旦它看到n(在这种情况下n = 3)这样的行,它就会打印出文件的其余部分。