change first line of a file using bash

2019-10-03 04:32发布

问题:

I need to change a single line in a file. It is always in the first line of the file.

It looks like:

h\tn0   n1  n2  n3  n4  n5  n6  n7  n8  n9  hilu    cjt 1   1000000

there is a tab in all gaps except after the h.

I would need to re-transform the line into

h  n1   n2  n3  n4  n5  n6  n7  n8  n9  
hilu    cjt 1   1000000

at the beginning o the line the \t thing and n0 needs to go and there needs to be a tab between h and n1. Then a newline needs to start before hilu but there should be no additional tab after n9

Ideally I would just feed my file to the script and it would not require writing an intermediate script to fill.

is there maybe an efficient version in Perl or python or so? I thought about R but then there are 1000 of lines in the file and only the first lien needs be changed...

tried to use the solution from jahid to run it from r with

> system(paste("sed -r \'1s/(.*)\t(REGION.*)/\1\n\2/;1s/\\t[^[:space:]]+//\'","arg_t1")) 
sed: -e expression #1, char 20: unterminated `s' command

with the suggest from the comm I get

> system(paste("sed -r \"1s/(.*)\t(REGION.*)/\1\n\2/;1s/\\t[^[:space:]]+//\"","arg_t1")) 
sed: -e expression #1, char 20: unterminated `s' command

回答1:

This isn't a bash job, it's a job for ed or sed. For instance, sed -i -e '1s/\\tn0\s*/\t/' -e '1s/\s*\(hilu\)/\n\1/' filename can do this. As Perl's foundation is a merging of shell, awk and sed, it can also be used similarly.

The editing itself isn't efficient because POSIX file semantics do not permit inserting or removing data, only (over)writing or truncating. This command therefore copies the file, with only the beginning altered. If done as part of a pipeline (just remove -i to output to stdout) it's practically zero cost. Also, with thousands of lines of data that's still pretty small by today's standards.



回答2:

Using sed (with Extended Regex):

sed -r '1s/(.*)\t(hilu.*)/\1\n\2/;1s/\\t[^[:space:]]+//' file

To change the file inplace:

sed -r --in-place '1s/(.*)\t(hilu.*)/\1\n\2/;1s/\\t[^[:space:]]+//' file


回答3:

To your example it could be something like this using Python. But also you need to open file and fetch first line inside variable line.

import re

line = 'h\tn0   n1  n2  n3  n4  n5  n6  n7  n8  n9  hilu    cjt 1   1000000'
line = re.sub('n9\s*','n9\n', re.sub('h.+n1', 'h\tn1', line))
print line