Search code examples
macosbashunixterminalqiime

append a code to every other line in a set of files


I am currently appending some sample codes to a set of files using the following code

cd /path/to/your/files
word='code'
base=1
for file in *; do sed -i -e "s/^/$word$base/" "${file}"; base=$(( $base + 1 )); done

This adds the term 'code1' in front of every line in file1, code2 in front of every line contained within file 2, etc.

What I would really like to do is tell this command to add 'code1' to every other line of code contained in file 1, file 2, etc. Is there a simple way to do this?

Bonus question- How can I tell this script to add 'code1' to every 4th line within each file, starting with the 2nd line, so that the lines in file 1 would read

line1
code1line2
line3
line4
line5
code1line6
line7
line8

file2 would follow the same pattern, but append the prefix code2.


Solution

  • For OS X sed, there is no step address function, so you'll need to use the N command to aggregate multiple lines.

    [2addr]N

    Append the next line of input to the pattern space, using an embedded newline character to separate the appended material from the original contents. Note that the current line number changes.

    For example:

    $ seq 1 10 | sed -e "{ N;s/.*/code1 &/; }"
    code1 1
    2
    code1 3
    4
    code1 5
    6
    code1 7
    8
    code1 9
    10
    

    If you're using GNU sed (as in linux), consult the Addresses section of the sed man page linked above:

    :first~step

    Match every step'th line starting with line first. For example, ''sed -n 1~2p'' will print all the odd-numbered lines in the input stream, and the address 2~5 will match every fifth line, starting with the second. first can be zero; in this case, sed operates as if it were equal to step. (This is an extension.)

    To demonstrate its use:

    seq 1 10 | sed -e "1~2s/.*/code1 &/"
    

    Prints:

    code1 1
    2
    code1 3
    4
    code1 5
    6
    code1 7
    8
    code1 9
    10
    

    Credit to Etan Reisner for the link in the comments.