web-dev-qa-db-fra.com

Unix: fusionnez plusieurs fichiers CSV avec le même en-tête en conservant l'en-tête du premier fichier

Je dois fusionner plusieurs fichiers CSV avec les mêmes en-têtes. Je dois conserver l'en-tête du premier fichier, supprimer les en-têtes de tous les autres fichiers, les fusionner et créer un fichier principal.

fichier 1:

Id,city,name ,location
1,NA,JACK,CA

fichier 2:

ID,city,name,location
2,NY,JERRY,NY

sortie:

Id,city,name,location
1,NA,JACK,CA
2,NY,JERRY,NY

Actuellement, j'utilise ce code:

ls *.csv | xargs -n 1 tail -n+2 > master.csv

Ce code fusionnera parfaitement les fichiers, mais comme j'ai besoin de l'en-tête du premier fichier, cela ne me donnera pas l'en-tête.

Que devrais-je faire?

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

testé sur Solaris Unix:

> cat file1.csv
Id,city,name ,location
1,NA,JACK,CA
>
> cat file2.csv
ID,city,name,location
2,NY,JERRY,NY
>
> nawk 'FNR==1 && NR!=1{next;}{print}' *.csv
Id,city,name ,location
1,NA,JACK,CA
2,NY,JERRY,NY
> 

Explication donnée par kevin-d :

FNR est le nombre de lignes (enregistrements) lues jusqu'à présent dans le fichier actuel. NR est le nombre de lignes lues globalement. Donc, la condition 'FNR == 1 && NR! = 1 {next;}' indique "Ignorez cette ligne s'il s'agit de la première ligne du fichier Actuel et si au moins 1 ligne a été lu dans son ensemble. " Cela a pour effet D'imprimer l'en-tête CSV du premier fichier tout en l'ignorant Dans le reste.

Lien pour la différence entre awk et nawk

56
Vijay
<?php
ini_set('auto_detect_line_endings', true);
$dir = "include/*.csv";
$returnVal = array();
foreach (glob($dir) as $file) {
    $header = null;
    $file = fopen($file, 'r') or die('Unable to open file!');
    while(($row = fgetcsv($file)) !== false){
        if($header === null){
            $header = $row;
            continue;
        }
        $newRow = array();
        for($i = 0; $i<count($row); $i++){

            $newRow[] = $row[$i];   
        }
        if($newRow[0] == null)
        break;
        else
        $returnVal[] = $newRow;
    }
    fclose($file);
}
//var_dump($returnVal);
$output = fopen("file.csv",'w') or die("Can't open output");
fputcsv($output, array('Date','close','open'));
foreach($returnVal as $product) {
    fputcsv($output, $product);
}

fclose ($ output) ou die ("Impossible de fermer php: // output"); ?>

0
Mahmudul Hasan

Si Perl est une option:

Perl -ne 'print if $. > 1 or ! $h; $h=1; close ARGV if eof' *.csv > master.csv

$. est le numéro de la ligne.
Il N'EST PAS réinitialisé automatiquement entre les fichiers, donc close ARGV if eof est nécessaire.
$h enregistre si l'en-tête a déjà été imprimé. 

0
Chris Koknat