Hamishm
Hamishm

Reputation: 21

Using bash to copy contents of row in one file to specific character location in another file

I'm new to bash and need help to copy Row 2 onwards from one file into a specific position (150 characters in) in another file. Through looking through the forum, I've found a way to include specific text listed at this position:

sed -i 's/^(.{150})/\1specifictextlisted/' destinationfile.txt

However, I can't seem to find a way to copy content from one file into this.

Basically, I'm working with these 2 starting files and need the following output:

File 1 contents:

Sequence
AAAAAAAAAGGGGGGGGGGGCCCCCCCCCTTTTTTTTT

File 2 contents:

chr2
tccccagcccagccccggccccatccccagcccagcctatccccagcccagcctatccccagcccagccccggccccagccccagccccggccccagccccagccccggccccagccccggccccatccccggccccggccccatccccggccccggccccggccccggccccggccccatccccagcccagccccagccccatccccagcccagccccggcccagccccagcccagccccagccacagcccagccccggccccagccccggcccaggcccagcccca

Desired output contents:

chr2 tccccagcccagccccggccccatccccagcccagcctatccccagcccagcctatccccagcccagccccggccccagccccagccccggccccagccccagccccggccccagccccggccccatccccggccccggccccatccccgAAAAAAAAAGGGGGGGGGGGCCCCCCCCCTTTTTTTTTgccccggccccggccccggccccggccccatccccagcccagccccagccccatccccagcccagccccggcccagccccagcccagccccagccacagcccagccccggccccagccccggcccaggcccagcccca

Can anybody put me on the right track to achieving this?

Upvotes: 0

Views: 456

Answers (3)

hek2mgl
hek2mgl

Reputation: 158000

You can use awk for that:

awk 'NR==FNR{a=$2;next}{print $1, substr($2, 0, 149) "" a "" substr($2, 150)}' file1 file2

Explanation:

# Total row number == row number in file
# This is only true when processing file1
NR==FNR {
    a=$2 # store column 2 in a variable 'a'
    next # do not process the block below
}
# Because of the 'next' statement above, this
# block gets only executed for file2
{
    # put 'a' in the middle of the second column and print it
    print $1, substr($2, 0, 149) "" a "" substr($2, 150)
}

I assume that both files contain only a single line, like in your example.


Edit: In comments you said that the files actually spread two lines, in that case you can use the following awk script:

# usage: awk -f this_file.awk file1 file2

# True for the second line in each file
FNR==2 {
    # Total line number equals line number in file
    # This is only true while we are processing file1
    if(NR==FNR) {
        insert=$0 # Store the string to be inserted in a variable
    } else {
        # Insert the string in file1
        # Assigning to $0 will modify the current line
        $0 = substr($0, 0, 149) "" insert "" substr($0, 150)
    }
}

# Print lines of file2 (line 2 has been modified above)
NR!=FNR

Upvotes: 1

micke
micke

Reputation: 1048

If the file is really huge instead of just 327 characters you might want to use dd:

dd if=chr2 bs=1 count=150 status=none of=destinationfile.txt
tr -d '\n' < Sequence >> destinationfile.txt
dd if=chr2 bs=1 skip=150 seek=189 status=none of=destinationfile.txt

189 is 150+length of Sequence.

Upvotes: 1

micke
micke

Reputation: 1048

You can use bash and read one char at the time from the file:

i=1
while read -n 1 -r; do
    echo -n "$REPLY"
    let i++
    if [ $i -eq 150 ]; then
        echo -n "AAAAAAAAAGGGGGGGGGGGCCCCCCCCCTTTTTTTTT"
    fi
done < chr2 > destinationfile.txt

This simply reads a char, echos it and increments the counter. If the counter is 150 it echos your sequence. You can replace the echo with a cat file | tr -d '\n'. Just make sure to remove any newlines, like here with tr. That is also why I use echo -n so it doesn't add any.

Upvotes: 0

Related Questions