开发者

How to edit number in column i-th of row n-th with bash shell

I have a data file like this:

1  7.1  3.506678
2  4.7  4.700778
3  5.9  5.901760
4  8.2  4.397694
.....

I would like to replace the third column of several lines, for example, 3rd and 4th line with the same number. Can anyone suggest a solution?

for i in 3 4;
do
    awk -v line="$i" 'NR==line {gsub(/4\.7/, "2\.3", $3)} 1'
done

开发者_StackOverflowExpected Output

1  7.1  3.506678
2  4.7  2.300778 #changed
3  5.9  2.301760 #changed
4  8.2  4.397694


First create a backup of your input file just in case.

Then maybe this loop could work?

for i in 3 4; do
   awk -v row="$i" -v column=3 -v new_string="some_value" 'BEGIN{OFS="\t"}NR==row{sub(/.*/,new_string,$column)} 1' stack.tsv > out.tsv
   cp out.tsv stack.tsv
done

INPUT:

cat stack.tsv
1   7.1 3
2   4.7 4
3   5.9 5
4   8.2 4

OUTPUT:

cat stack.tsv
1   7.1 3
2   4.7 4
3   5.9 some_value
4   8.2 some_value


$ awk 'BEGIN{FS=OFS="  "; a[2]; a[3]} NR in a{sub(/.../,2.3,$3)} 1' file
1  7.1  3.506678
2  4.7  2.300778
3  5.9  2.301760
4  8.2  4.397694

or in general for many lines:

$ awk 'BEGIN{split("2 3",tmp); for (i in tmp) a[tmp[i]]; FS=OFS="  "} NR in a{sub(/.../,2.3,$3)} 1' file
1  7.1  3.506678
2  4.7  2.300778
3  5.9  2.301760
4  8.2  4.397694


Repeatedly running Awk on the same file is inelegant, slow, and somewhat brittle. Refactor your script to perform all the changes in one go.

awk -v lines=3:4 'BEGIN { i = split(lines, n, ":"); for(j=1; j<=i; ++j) line[n[j]]++ }
  FNR in line { sub(/^[0-9]\.[0-9]/, "2\.3", $3)} 1' file >newfile

Awk will mangle (or, well, normalize) the spacing on the lines it modifies; if this is a significant problem, there are ways to preserve the original spacing, but that will complicate the solution.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜