Adding text to the end of multiple files, minus one line( Adding return 0; at the end of each program in C)

1

I have a bunch of C programs from K&R and of course, no return statement. I was wondering if there was a way to cat to the end of each file (except one line before the end, so EOF - 1) the statement "\treturn 0;" including the tab before it and the newline after it.

user339365

Posted 2014-06-28T04:39:11.617

Reputation: 145

Welcome to Super User! Please always include your OS. Solutions very often depend on the Operating System being used. Are you using Windows, Unix, Linux, BSD, OSX, something else? Which version? – terdon – 2014-06-28T13:57:26.360

Answers

0

A few options (all of which are pointless and do exactly the same as for f in *c; do echo -e "\treturn 0;" >> "$f"; done):

  1. Perl

    tmp=$(mktemp)
    for f in *c; do
        perl -lpe 'END{print "\treturn 0;"}' "$f" > $tmp && mv $tmp "$f"
    done
    
  2. awk

    tmp=$(mktemp)
    for f in *.c; do
        awk '1;END{print "\treturn 0;"}' "$f" > $tmp && mv $tmp "$f"
    done
    
  3. Cat the file into a temp file, add the line, and rename the temp file:

    tmp=$(mktemp)
    for f in *.c; do
        cat "$f" > $tmp;
        echo -e "\treturn 0;" >> $tmp
        mv $tmp "$f"
    done
    

terdon

Posted 2014-06-28T04:39:11.617

Reputation: 45 216

I’m baffled as to why the OP accepted this answer, since it’s not what he asked for. All three options simply append the return statement to the file, which could be done as easily by echo -e "\treturn 0" >> "$f". But the question asks how to inject the return statement before the last line. (Also, you left off the semicolon.) P.S. Congratulations on winning the election. – Scott – 2014-07-01T00:24:23.907

@Scott no more baffled than I to tell you the truth. As for echo >> file I had a serious problem between the keyboard and my brain there. For some reason, which I can no longer remember, I thought these approaches do something different. Presumably I was thinking of something like what your answer does and then decided to reinvent the wheel. I can't do much about it since it's accepted but you may as well give it a downvote so at least yours will rise up. P.S. Thanks :) – terdon – 2014-07-01T00:31:51.810

1

A few options:

  1. Unix:

    tmp=$(mktemp)
    for f in *c; do
        head --lines=-1 "$f" > "$tmp"
        echo -e "\treturn 0;" >> "$tmp"
        tail -1 "$f" >> "$tmp"
        mv "$tmp" "$f"
    done
    
  2. awk:

    tmp=$(mktemp)
    for f in *.c; do
        awk 'NR > 1 { print prev_line; }
                    { prev_line = $0; }
                END { print "\treturn 0;"; print; }' "$f" > "$tmp" \
        &&  mv "$tmp" "$f"
    done
    
  3. sed:

    for f in *.c; do
        sed -i '$i\
    \treturn 0;' "$f"
    done
    

Scott

Posted 2014-06-28T04:39:11.617

Reputation: 17 653