Skip to content
Advertisement

How can I merge two files in one using BASH or Python script?

We assume that I have two files like this:

File1 :

F: user1 password1 
F: user2 password2 
F: user3 password3

File2 :

server1 24000
server2 24000
server3 24000
server4 24000

I want to combine them in order to get one file with this output file :

OuputFile :

C: server1 24000  user1 password1
C: server2 24000  user1 password1
C: server3 24000  user1 password1
C: server4 24000  user1 password1
C: server1 24000  user2 password2
C: server2 24000  user2 password2
C: server3 24000  user2 password2
C: server4 24000  user2 password2
C: server1 24000  user3 password3
C: server2 24000  user3 password3
C: server3 24000  user3 password3
C: server4 24000  user3 password3

So, in Windows, I made this batch file to get what I expected, but, I have no idea how to do it in BASH (Bourne-Again shell) or in Python script.

The Batch File :

@echo off
set file1=file1.txt
set file2=file2.txt
Set Output=Output_CCCam.cfg
If Exist %Output% Del %Output%
for /f "tokens=2 delims=:" %%a in ('Type "%file1%"') do (
    for /f "delims=" %%b in ('Type "%file2%"') do (
        >>%Output% echo C: %%b %%a
    )
)
Start "" Notepad %Output% 

Advertisement

Answer

A Bash solution

#!/bin/bash

while IFS= read -r line1; do
    while IFS= read -r line2; do
        printf "C: %s  %sn" "$line2" "${line1/#F: }"
    done < file2
done < file1

This loops over file1, and for each line of file1 loops over file2. The printf line assembles the output, and the parameter expansion for line removes the leading F: .

Result:

C: server1 24000  user1 password1
C: server2 24000  user1 password1
C: server3 24000  user1 password1
C: server4 24000  user1 password1
C: server1 24000  user2 password2
C: server2 24000  user2 password2
C: server3 24000  user2 password2
C: server4 24000  user2 password2
C: server1 24000  user3 password3
C: server2 24000  user3 password3
C: server3 24000  user3 password3
C: server4 24000  user3 password3

A solution with join and sed

This would work as well:

join -j 50 -o 2.1,1.1 -t '~' file1 file2 | sed s'/~F:/ /;s/^/C: /'

This is a slight abuse of join. -j 50 says to join on matching field number 50, which doesn’t exist and is thus considered equal for all lines, resulting in the Cartesian product of the two files:

$ join -j 50 file1 file2
 F: user1 password1 server1 24000
 F: user1 password1 server2 24000
 F: user1 password1 server3 24000
 F: user1 password1 server4 24000
 F: user2 password2 server1 24000
 F: user2 password2 server2 24000
 F: user2 password2 server3 24000
 F: user2 password2 server4 24000
 F: user3 password3 server1 24000
 F: user3 password3 server2 24000
 F: user3 password3 server3 24000
 F: user3 password3 server4 24000

To get the lines into proper order, we specifiy the output format with -o 2.1,1,1. Because the default field delimiter is whitespace, we specify a character that is not contained in the input as the new delimiter with -t '~':

$ join -j 50 -o 2.1,1.1 -t '~' file1 file2
server1 24000~F: user1 password1
server2 24000~F: user1 password1
server3 24000~F: user1 password1
server4 24000~F: user1 password1
server1 24000~F: user2 password2
server2 24000~F: user2 password2
server3 24000~F: user2 password2
server4 24000~F: user2 password2
server1 24000~F: user3 password3
server2 24000~F: user3 password3
server3 24000~F: user3 password3
server4 24000~F: user3 password3

And finally, we replace ~F: with a space on each line and prepend C: using sed:

$ join -j 50 -o 2.1,1.1 -t '~' file1 file2 | sed 's/~F:/ /;s/^/C: /'
C: server1 24000  user1 password1
C: server2 24000  user1 password1
C: server3 24000  user1 password1
C: server4 24000  user1 password1
C: server1 24000  user2 password2
C: server2 24000  user2 password2
C: server3 24000  user2 password2
C: server4 24000  user2 password2
C: server1 24000  user3 password3
C: server2 24000  user3 password3
C: server3 24000  user3 password3
C: server4 24000  user3 password3

If the order of the lines doesn’t matter, this can be slightly shortened to

$ join -j 50 file2 file1 | sed 's/F://;s/^/C:/'
C: server1 24000  user1 password1
C: server1 24000  user2 password2
C: server1 24000  user3 password3
C: server2 24000  user1 password1
C: server2 24000  user2 password2
C: server2 24000  user3 password3
C: server3 24000  user1 password1
C: server3 24000  user2 password2
C: server3 24000  user3 password3
C: server4 24000  user1 password1
C: server4 24000  user2 password2
C: server4 24000  user3 password3
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement