Объединение файлов CSV: добавление вместо слияния

Итак, в основном я хочу объединить несколько файлов CSV. Im, используя следующий script, чтобы сделать это:

paste -d , *.csv > final.txt

Однако это сработало для меня в прошлом, но на этот раз это не сработало. Он добавляет данные рядом друг с другом, а не под друг друга. Например, два файла, которые содержат записи в следующем формате

CreatedAt   ID
Mon Jul 07 20:43:47 +0000 2014  4.86249E+17
Mon Jul 07 19:58:29 +0000 2014  4.86238E+17
Mon Jul 07 19:42:33 +0000 2014  4.86234E+17

При объединении дайте

CreatedAt   ID CreatedAt    ID
Mon Jul 07 20:43:47 +0000 2014  4.86249E+17 Mon Jul 07 18:25:53 +0000 2014  4.86215E+17
Mon Jul 07 19:58:29 +0000 2014  4.86238E+17 Mon Jul 07 17:19:18 +0000 2014  4.86198E+17
Mon Jul 07 19:42:33 +0000 2014  4.86234E+17 Mon Jul 07 15:45:13 +0000 2014  4.86174E+17
                                            Mon Jul 07 15:34:13 +0000 2014  4.86176E+17

Кто-нибудь знает, в чем причина этого? Или что я могу сделать, чтобы заставить слиться ниже записей?

Ответ 1

Предполагая, что все файлы csv имеют одинаковый формат и все начинаются с одного и того же заголовка, вы можете написать небольшой скрипт, как показано ниже, чтобы добавить все файлы только в один и взять только один раз заголовок.

#!/bin/bash
OutFileName="X.csv"                       # Fix the output name
i=0                                       # Reset a counter
for filename in ./*.csv; do 
 if [ "$filename"  != "$OutFileName" ] ;      # Avoid recursion 
 then 
   if [[ $i -eq 0 ]] ; then 
      head -1  "$filename" >   "$OutFileName" # Copy header if it is the first file
   fi
   tail -n +2  "$filename" >>  "$OutFileName" # Append from the 2nd line each file
   i=$(( $i + 1 ))                            # Increase the counter
 fi
done

Заметки:

  • Команда head -1 или head -n 1 печатает первую строку файла (head -n 1).
  • tail -n +2 печатает хвост файла, начиная со строк № 2 (+2)
  • Тест [... ] используется для исключения выходного файла из списка ввода.
  • Выходной файл перезаписывается каждый раз.
  • Команда cat a.csv b.csv > X.csv может быть просто использована для добавления a.csv и b csv в один файл (но вы копируете заголовок 2 раза).

Команда paste вставляет файлы один на другой. Если в файле есть пробелы в виде строк, вы можете получить вывод, о котором вы сообщили выше.
Использование -d , просит paste command, чтобы определить поля, разделенные запятой ,, но это не так для формата файлов, которые вы сообщили выше.

Вместо этого команда cat объединяет файлы и печатает на стандартном выводе, что означает, что она записывает один файл за другим.

Синтаксис одиночных опций приведен в разделе " man head или " man tail (в некоторых версиях можно использовать head -1 а вместо head -n 1)...

Ответ 2

Большое спасибо @wahwahwah. Я использовал ваш script для создания nautilus-action, но он корректно работает только с этими изменениями:

#!/bin/bash

for last; do true; done

OutFileName=$last/RESULT_`date +"%d-%m-%Y"`.csv                       # Fix the output name

i=0                                       # Reset a counter
for filename in "$last/"*".csv"; do

 if [ "$filename" != "$OutFileName" ] ;      # Avoid recursion 
 then 
   if [[ $i -eq 0 ]] ; then 
      head -1  "$filename" > "$OutFileName" # Copy header if it is the first file
   fi
   tail -n +2  "$filename" >> "$OutFileName" # Append from the 2nd line each file
   i=$(( $i + 1 ))                        # Increase the counter
 fi
done