In this short tutorial, I'll show you several ways to merge multiple files with bash in Linux Mint. The examples will cover merging with and without the headers.

It's assumed that CSV files are identical if not you can check Python solution: How to merge multiple CSV files with Python

Let's have 2 csv files:

  • file1.csv
col1 col2 col3
1 Jake 100
2 John 95
3 Joe 87
  • file2.csv
col1 col2 col3
21 Ema 96
22 Eli 88
23 Erica 100
24 Emily 77
  • merged.csv - the result after concatenation:
col1 col2 col3
1 Jake 100
2 John 95
3 Joe 87
21 Ema 96
22 Eli 88
23 Erica 100
24 Emily 77

merge-multiple-csv-files-linux-mint

Example 1: Append multiple CSV files in bash with(out) header

The first example will merge multiple CSV or text files by combining head and tail commands in Linux. If the files don't have headers only head is enough:

tail -n+1 -q *.csv >> merged.out

In case of headers - head can get the header from one file and the values to be collected with tail

head -n 1 file1.csv > merged.out && tail -n+2 -q *.csv >> merged.out

Note 1: if the last line in the file doesn't have new line separator this way will produce results:

3,Joe,87col1,col2,col3

In this case you can check the second example.

Note 2: parameter -q is used to remove extra text for command tail.

Example 2: Merge CSV files without new line in Linux terminal

This example shows an improved version of the first one which solves the problem of missing a new line at the end of each CSV file. This is the short version:

head -n 1 1.csv > combined.out
for f in *.csv; do     tail -n 2 "$f";     printf "\n"; done >> combined.out

and prettified shell version will be:

for f in *.csv; do     
    tail -n 2 "$f";     
    printf "\n";
done >> merged.out

result:

col1,col2,col3
1,Jake,100
2,John,95
3,Joe,87
21,Ema,96
22,Eli,88
23,Erica,100
24,Emily,77

Example 3: Concatenate two CSV files in Linux with awk (including headers)

Third example shows how to merge two and more files by using the command awk. If all files have headers the command will take only 1 header from one file. The rest of the data will be appended to the end of the file. The command is:

awk 'FNR==1 && NR!=1{next;}{print}' *.csv >> merged.csv

result:

col1,col2,col3
1,Jake,100
2,John,95
3,Joe,87
21,Ema,96
22,Eli,88
23,Erica,100
24,Emily,77

where the condition FNR==1 && NR!=1 reads the first line of the first file and skips the first line for the rest.

If you don't care for the headers than you can change it to:

awk 'FNR==0{next;}{print}' *.csv >> merged.csv

result:

col1,col2,col3
1,Jake,100
2,John,95
3,Joe,87
col1,col2,col3
21,Ema,96
22,Eli,88
23,Erica,100
24,Emily,77