简体   繁体   中英

How to multiple a number by 2 (double)present in a particular line number of a file, in Linux?

File_A

Name: John Smith
Grade: 8
Institute: Baldwin
Number of entries: 125
State: Texas

File_B

Name: David Buck
Grade: 9
Institute: High Prime
Number of entries: 123
State: California

There are many such similar files in which the Number of entries (present at line number 4 in all files) has to doubled.

For File_A it should be 250 and for File_B 246.

How to do this for all files in Linux?(using sed or awk or any other commands)

Tried commands:

sed -i '4s/$2/$2*2/g' *.txt               (nothing happening from this)
awk "FNR==4 {sub($2,$2*2)}" *.txt         (getting syntax error)

With your shown samples please try following awk code. Simple explanation would be look/search for string /Number of entries: and then multiply 2 into value of last field and save it within itself, then print lines by mentioning 1 .

awk '/Number of entries:/{$NF = ($NF * 2)} 1' File_A File_B

Run above command it will print output on screen, once you are Happy with output and want to save output into Input_file itself then you can try awk 's -inplace option(available in GNU awk 4.1+ version etc).

Also if your files extension is.txt then pass it to above awk program itself, awk can read multiple files itself.

This might work for you (GNU sed and shell):

sed -Ei '4s/(.* )(.*)/echo "\1$((\2*2))"/e' file1 file2 filen

For line four of each file input, split the values into two back references and echo back those values using shell arithmetic to double the second value.

NB The -i option allows for address of line four to be found in all input files and those files to be amended in situ.

Using sed

$ sed '/^Number of entries/s/[[:digit:]]\+/$((&*2))/;s/^/echo /e' input_file

I want to explain why what you have tried failed, firstly

sed -i '4s/$2/$2*2/g' *.txt

$ has not special meaning for GNU sed , that it is literal dollar sign, also GNU sed does not support arithmetic, so above command is: at 4th line replace dollar sign folowed by 2 using dollar sign followed by 2 followed by asterix followed by 2 and do so globally. You do not have literal $2 at 4th line of file which is firstly rammed so nothing happens.

awk "FNR==4 {sub($2,$2*2)}" *.txt 

You should not use " for enclosing awk command unless you want to summon mind-boggling bugs. You should use ' in which case syntax error will be gone, however behavior will be not as desired. In order to do that your code might be reworked to

awk 'BEGIN{FS=OFS=": "}FNR==4{$2*=2}{print}' *.txt

Observe that I specify FS and OFS to inform GNU AWK that field are separated and should be separated by : rather than one-or-more whitespace characters (default) and do not use sub function (which is for working with regular expression), but rather simply increase 2 times operator ( *=2 ) and I also print line, as without it output would be empty. If you want to know more about FS or OFS read 8 Powerful Awk Built-in Variables – FS, OFS, RS, ORS, NR, NF, FILENAME, FNR

Thank you for all the answers. With your help I was able to figure out simple solution by understanding and combining your answers.

Here it is (which worked in my environment):

To display on terminal: awk 'FNR==4 {sub($4,$4*2)} 1' File_A

To move to some file: awk 'FNR==4 {sub($4,$4*2)} 1' File_A > temp_A

To perform changes inside file using inplace: awk -i inplace 'FNR==4 {sub($4,$4*2)} 1' *.txt

$4 being 4th parameter in the line; FNR==4 being the line number 4; 1 at the end helps in printing everything

 mawk 'BEGIN{ _+=_^=FS=OFS="Number of entries: " } NF<_ || $NF *=_'
Name: John Smith
Grade: 8
Institute: Baldwin
Number of entries: 250
State: Texas
Name: David Buck
Grade: 9
Institute: High Prime
Number of entries: 246
State: California

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM