Marcus Thornton
Marcus Thornton

Reputation: 6193

How to append the number of line in front of the generated file in shell script without producing a temp file

I have a program to generate a file like this:

./program1 $parameter > tempfile
lineNum=`wc -l tempfile | awk '{print $1}'`
echo $lineNum > myfile
cat tempfile >> myfile
rm -f tempfile

I wonder if there is a way to archive this without producing a "tempfile"? I think my way is somehow redundant and hope there will be a better way.

Upvotes: 0

Views: 113

Answers (5)

Sylvain Leroux
Sylvain Leroux

Reputation: 52040

For the fun -- and assuming your files are sufficiently small to not exceed the available memory -- you could use only bash internals for that task:

#!/bin/bash

# ...

./program1 $parameter |
    ( mapfile arr; echo ${#arr[@]}; IFS=""; echo -n "${arr[*]}" )

Upvotes: 0

Sylvain Leroux
Sylvain Leroux

Reputation: 52040

This is not really without using a temporary (as sed -i will do it for you) but...

#!/bin/bash
count=$(./program1 $parameter | tee outputfile | wc -l)
sed -i 1i${count} outputfile

This might have the advantage of not requiring to load the whole file in memory. Depending your data file this might or might not be an issue.

Upvotes: 1

Aserre
Aserre

Reputation: 5072

other solution : use nl. It's a tool that was designed to do just that.

./program1 $parameter | nl -w1 > myfile

Here, -w1 is used to specify line numbers are separated by 1 tab

output :

1    something
2    somethingelse
3
4    and now for something completly different

If you don't want to use tab as a separator, use the flag -s"X", where X is the separator you want (1 space, 2 spaces, a letter, ...). ./program1 $parameter | nl -w1 -s" " > myfile will yield :

1 something
2 somethingelse
3
4 and now for something completly different

Upvotes: 1

konsolebox
konsolebox

Reputation: 75568

You can just use awk:

./program1 "$parameter" | awk '{lines[++n]=$0}END{print n;for(i=1;i<=n;++i)print lines[i]}' > myfile

Example:

seq --format='Inline Text %.0f' 1 10 | awk '{lines[++n]=$0}END{print n;for(i=1;i<=n;++i)print lines[i]}'

Output:

10
Inline Text 1
Inline Text 2
Inline Text 3
Inline Text 4
Inline Text 5
Inline Text 6
Inline Text 7
Inline Text 8
Inline Text 9
Inline Text 10

Upvotes: 0

sat
sat

Reputation: 14959

You can use this,

sed -i "1i$(wc -l myfile | cut -d' ' -f1)" myfile

(OR)

sed -i "1i$(wc -l < myfile )" myfile

Ex:

./program1 $parameter > myfile
sed -i "1i$(wc -l myfile | cut -d' ' -f1)" myfile

Upvotes: 1

Related Questions