web-dev-qa-db-fra.com

Fusion de fichiers CSV: ajouter au lieu de fusionner

Donc, fondamentalement, je veux fusionner quelques fichiers CSV. J'utilise le script suivant pour le faire: 

paste -d , *.csv > final.txt

Cependant, cela a fonctionné pour moi dans le passé, mais cette fois, cela ne fonctionne pas. Il ajoute les données les unes à côté des autres et non les unes sous les autres. Par exemple, deux fichiers contenant des enregistrements au format suivant

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

Lorsque fusionné donner 

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

Quelqu'un saurait-il quelle est la raison derrière cela? Ou ce que je peux faire pour forcer la fusion en dessous des enregistrements? 

13
user2233834

En supposant que tous les fichiers csv ont le même format et commencent tous par le même en-tête, Vous pouvez écrire un petit script comme suit pour ajouter tous les fichiers dans un seul et pour ne prendre qu'un seul chronométrez l'en-tête .

#!/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

Remarques: 

  • La commande head -1 ou head -n 1 imprime la première ligne d'un fichier (l'en-tête).
  • Le tail -n +2 imprime la queue d'un fichier à partir des lignes numéro 2 (+2)
  • Test [ ... ] est utilisé pour exclure le fichier de sortie de la liste d'entrée.
  • Le fichier de sortie est réécrit à chaque fois. 
  • La commande cat a.csv b.csv > X.csv peut être simplement utilisée pour ajouter a.csv et b csv dans un seul fichier (mais vous copiez 2 fois l'en-tête).

La commande paste colle les fichiers les uns sur les autres. Si un fichier contient des espaces blancs sous forme de lignes, vous pouvez obtenir la sortie indiquée ci-dessus.
L'utilisation de -d , demande à paste command de définir des champs séparés par une virgule ,, mais ce n'est pas le cas du format des fichiers que vous avez indiqué ci-dessus.

La commande cat concatène à la place des fichiers et s’imprime sur la sortie standard, ce qui signifie qu’elle écrit un fichier après l’autre. 

Reportez-vous à man head ou man tail pour la syntaxe des options simples (certaines versions permettent head -1 autres à la place de head -n 1) ... 

32
Hastur

Merci beaucoup @wahwahwah. J'ai utilisé votre script pour faire nautilus-action , mais cela ne fonctionne correctement qu'avec les modifications suivantes:

#!/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
0
Andrea