Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

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
done

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
done
share|improve this question

2 Answers 2

up vote 3 down vote accepted

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

 i=<line-number>
 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.

share|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:

#!/bin/sh
# 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
esac

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
then
    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
else
    echo "replace5: failed, $filea unchanged" 1>&2
    exit 1
fi
rm -f $new $old
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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