Can i do the following in the terminal? (written in pseudo-code)

for (int i=1;i<=5;i++) {
replace first line of fileout.text by i-th line of filein.txt 

i guess it somehow involves using sed, but i don't know how to sed from one file to another.

EDIT: I frame Htorque's answer inside a loop:

for (( i = 1 ; i <= 10 ; i++ )); do
    line=$(sed -n "${i}p" filein.txt)
    sed -i "1c\\$line" fileout.txt

which works like a charm. It is possible to replace the fixed string '10' in the counter by the actual number of lines of filein.txt:

nline=$(sed -n '$=' filein.txt)
for (( i = 1 ; i <= $nline ; i++ )); do
    line=$(sed -n "${i}p" filein.txt)
    sed -i "1c\\$line" fileout.txt

To replace the first line of FILE.out with the i-th line of FILE.in I'd do:

 line=$(sed -n "${i}p" FILE.in)
 sed -i "1c\\$line" FILE.out

If i doesn't exist in FILE.in, then the first line of FILE.out would be deleted (empty).

If $line contains any special characters (eg. backslash, dollar), then you'd need to escape those.

Not 100% sure this couldn't break elsewhere.

| improve this answer | |
  • @Htorque's:> Thanks, it works like a charm (see edit question). However there is a little catch/icing on the cake (see second part of the question's edit). Would you know of a fix ? – user2413 Nov 3 '10 at 11:55
  • I actually don't understand what you're trying to do (you are replacing the same line over and over again?). Is this the whole code? As for your follow-up question: you want to store the result of that command in nline, not the command. So you'd do nline=$(sed -n "$=" filein.txt). Just be aware that this alone could break the for-loop if filein.txt were an empty file. – htorque Nov 3 '10 at 12:12
  • actually, in the 'real' code, filein.txt contains a list of 1000 parameters (one per lines). fileout.txt is a script (that is run in bash), calling an executable that uses these parameters. I don't have the source of that last executable so i'm proceeding this way. (do you think i should add these info to the question, for future users ?). – user2413 Nov 3 '10 at 13:57
  • " Just be aware that this alone could break the for-loop if filein.txt were an empty file". Actually that's exactly the behavior i'm looking for :) – user2413 Nov 3 '10 at 13:57

There are two parts to the program: getting the output you want and then replacing the contents of the original file with that output:

# output the first five lines of the first argument
# followed by all but the first of the second argument
# if successful, replace the second argument with the
# result

# cribbed almost entirely from Kernighan & Pike's
$ "The Unix Programming Environment" script "overwrite"

case $# in
0|1)        echo 'Usage: replace5 filea fileb' 1>&2; exit 2

filea=$1; fileb=$2
new=/tmp/$$.new; old=/tmp/$$.old
trap 'rm -f $new; exit 1' 1 2 15    # clean up files

# collect input
if head -5 $filea >$new && tail -n +2 $fileb >> $new
    cp $filea $old   # save original file
    trap 'trap "" 1 2 15; cp $filea $old   # ignore signals
          rm -f $new $old; exit 1' 1 2 15   # during restore
    cp $new $filea
    echo "replace5: failed, $filea unchanged" 1>&2
    exit 1
rm -f $new $old
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.