phenomenon
phenomenon

Reputation: 223

Adding an empty line between first and second line in a text file

A file (foo.csv) contain entries (four columns) as follows:

A 5.3 3.2 1.2 
A 2.1 3.4 6.7
A 3.4 2.1 5.6 
A 0.4 2.2 4.2

In this file, I want to add the total number of lines in the first line followed by an empty line.

I want the output to be as follow.

4

A 5.3 3.2 1.2 
A 2.1 3.4 6.7
A 3.4 2.1 5.6 
A 0.4 2.2 4.2

Here is what I tried.

#to get the total number of lines in the file foo.csv
t=$((wc -l foo.csv | cut -d" " -f1))
#to add an empty line 
sed -i "1i\\" foo.csv
#to insert the total number at the top; this works fine.
sed -i "1i $t" foo.csv

I need to do this for a bunch of files. So, script will be useful. The problem seems to be in sed -i "1i\\" foo.csv. How to correct this?

Upvotes: 3

Views: 1296

Answers (4)

potong
potong

Reputation: 58351

This might work for you (GNU sed):

sed -e '1e wc -l <file' -e '1H;1g' file

or to do everything in sed:

sed -e '1e sed "$=;d" file' -e '1H;1g' file

This uses the e command to evaluate unix commands. Normally this is done using the e flag to the s command, but it can be used following an address, as in this situation.

An alternative, using a pipe:

wc -l <file | sed '1G' - file

or:

sed '$=;d' file | sed '1G' - file

Use the result of a wc or sed command as the first input file.

On retrospect, the easiest solution (although not the most efficient):

sed 'H;$!d;=;x' file

Which slurps the file into the hold space and inserts the number of lines and a blank line before printing out the hold space.

Upvotes: 0

karakfa
karakfa

Reputation: 67467

do the line counting with awk as well.

$ awk 'NR==FNR{next} FNR==1{print NR-1 ORS}1' file{,}

or, with tac...tac

$ tac file | awk '1; END{print ORS NR}' | tac

Upvotes: 3

David C. Rankin
David C. Rankin

Reputation: 84521

You can do it quite simply using sed with the 0,addr2 form (see man sed under "Addresses") with general substitution, e.g.

$ sed '0,/^/s/^/4\n\n/' file
4

A 5.3 3.2 1.2
A 2.1 3.4 6.7
A 3.4 2.1 5.6
A 0.4 2.2 4.2

The sed expression simply finds the first occurrence of the beginning of the line 0,/^/ and then substitutes the beginning of the line with 4\n\n, using s/^/4\n\n/

Add the -i option to edit-in-place (or -i.bak to create a back of the original (e.g. file.bak) while editing in place.

If you are interested in setting the number of lines, then you can simply get the lines with wc -l using command substitution, e.g.

$ sed "0,/^/s/^/$(wc -l <file2)\n\n/" file2
8

A 5.3 3.2 1.2
A 2.1 3.4 6.7
A 3.4 2.1 5.6
A 0.4 2.2 4.2
A 5.3 3.2 1.2
A 2.1 3.4 6.7
A 3.4 2.1 5.6
A 0.4 2.2 4.2

(note: the use of double-quotes instead of single-quotes to allow expansion of the command substitution)

Upvotes: 1

RavinderSingh13
RavinderSingh13

Reputation: 133428

If you are ok with awk could you please try following.

awk -v line=$(wc -l < Input_file) 'FNR==1{print line ORS} 1'  Input_file

In case you want to add output into Input_file itself then append > temp_file && mv temp_file Input_file to above code then.

Explanation: Adding explanation for above code too now.

awk -v line=$(wc -l < Input_file  ) '       ##Creating variable line whose value is bash command wc -l to get line count for Input_file as per OP request.
FNR==1{                                     ##Checking if line number is 1 here then do following.
  print line ORS                            ##Printing variable line here with ORS whose value is new line here.
}                                           ##Closing FNR block here.
1                                           ##awk works on method of pattern and action mentioning 1 making condition TRUE and no action will make print to happen.
'  Input_file                               ##Mentioning Input_file name here.

Upvotes: 2

Related Questions