2
votes

Comment insérer le nom de fichier et l'en-tête au début d'un csv à l'aide des outils sed / awk / bash / unix?

Mes noms de fichiers sont comme ceci.

customer,first_name,middle_name,last_name,gender,email,phone_number,address,city,state,country,date_order_start,date_order_complete,invoice_number,invoice_date,item,item_price,quantity,cost,job_name,job_price,total_cost
Chae,Jesusa,Cummings,Female,deifier2040@live.com,775-861-8750,911 Hauser Pike,Moline,Georgia,Cameroon,2016-06-29,2016-07-16,36298,2016-07-17,Acer,493.86,14,354.77,Broken,123.68,898.13
first_name,middle_name,last_name,gender,email,phone_number,address,city,state,country,date_order_start,date_order_complete,invoice_number,invoice_date,item,item_price,quantity,cost,job_name,job_price,total_cost
Fleta,Rosette,Hurley,Other,tobacconist1857@outlook.com,1-952-701-1210,35 Freelon Arcade,Beaverton,Rhode Island,Cayman Islands,2009-06-08,2009-06-29,39684,2009-07-01,NVIDIA GeForce GTX 980,474.31,16,395.79,Broken,157.53,1088.04
Bennett,Dennis,George,Male,dona1910@live.com,(980) 033-4131,505 Robert C Levy Arcade,Wellington,Louisiana,Mexico,2019-05-09,2019-05-19,37938,2019-05-21,8GB,187.67,16,205.77,Service,170.21,1007.85
Tommye,Pamula,Diaz,Other,dovelet1967@live.com,204.950.4445,1001 Canby Boulevard,Edinburg,Massachusetts,Gambia,2004-05-02,2004-05-24,31364,2004-05-26,Lenovo,137.21,13,193.63,Replacement,246.43,934.31
Albert,Jerrold,Cohen,Other,bolio2036@live.com,+1-(122)-459-8491,1181 Baden Avenue,Menomonee Falls,Texas,Tajikistan,2019-08-03,2019-08-12,37768,2019-08-15,Intel® Iris™ Graphics 6100,396.46,17,223.02,Service,118.53,960.27
Louetta,Collene,Best,Fluid,dinner1922@live.com,1-506-051-7050,923 Barry Viaduct,Laurel,Illinois,St. Barthélemy,2009-03-02,2009-03-06,39557,2009-03-07,AMD Radeon R9 M395X,133.9,11,198.49,Fix,178.54,1055.32
Kandace,Wesley,Diaz,Female,closterium1820@yahoo.com,+1-(777)-098-5414,341 Garlington Run,Santa Maria,New Jersey,Mexico,2005-10-09,2005-10-10,30543,2005-10-14,Samsung,590.29,5,354.85,Service,292.56,1032.22

Ils contiennent ce qui suit.

100..00.csv

first_name,middle_name,last_name,gender,email,phone_number,address,city,state,country,date_order_start,date_order_complete,invoice_number,invoice_date,item,item_price,quantity,cost,job_name,job_price,total_cost
10000000,first_name,middle_name,last_name,gender,email,phone_number,address,city,state,country,date_order_start,date_order_complete,invoice_number,invoice_date,item,item_price,quantity,cost,job_name,job_price,total_cost
10000000,Chae,Jesusa,Cummings,Female,deifier2040@live.com,775-861-8750,911 Hauser Pike,Moline,Georgia,Cameroon,2016-06-29,2016-07-16,36298,2016-07-17,Acer,493.86,14,354.77,Broken,123.68,898.13

first_name,middle_name,last_name,gender,email,phone_number,address,city,state,country,date_order_start,date_order_complete,invoice_number,invoice_date,item,item_price,quantity,cost,job_name,job_price,total_cost
10000001,first_name,middle_name,last_name,gender,email,phone_number,address,city,state,country,date_order_start,date_order_complete,invoice_number,invoice_date,item,item_price,quantity,cost,job_name,job_price,total_cost
10000001,Fleta,Rosette,Hurley,Other,tobacconist1857@outlook.com,1-952-701-1210,35 Freelon Arcade,Beaverton,Rhode Island,Cayman Islands,2009-06-08,2009-06-29,39684,2009-07-01,NVIDIA GeForce GTX 980,474.31,16,395.79,Broken,157.53,1088.04
10000001,Bennett,Dennis,George,Male,dona1910@live.com,(980) 033-4131,505 Robert C Levy Arcade,Wellington,Louisiana,Mexico,2019-05-09,2019-05-19,37938,2019-05-21,8GB,187.67,16,205.77,Service,170.21,1007.85
10000001,Tommye,Pamula,Diaz,Other,dovelet1967@live.com,204.950.4445,1001 Canby Boulevard,Edinburg,Massachusetts,Gambia,2004-05-02,2004-05-24,31364,2004-05-26,Lenovo,137.21,13,193.63,Replacement,246.43,934.31
10000001,Albert,Jerrold,Cohen,Other,bolio2036@live.com,+1-(122)-459-8491,1181 Baden Avenue,Menomonee Falls,Texas,Tajikistan,2019-08-03,2019-08-12,37768,2019-08-15,Intel® Iris™ Graphics 6100,396.46,17,223.02,Service,118.53,960.27
10000001,Louetta,Collene,Best,Fluid,dinner1922@live.com,1-506-051-7050,923 Barry Viaduct,Laurel,Illinois,St. Barthélemy,2009-03-02,2009-03-06,39557,2009-03-07,AMD Radeon R9 M395X,133.9,11,198.49,Fix,178.54,1055.32
10000001,Kandace,Wesley,Diaz,Female,closterium1820@yahoo.com,+1-(777)-098-5414,341 Garlington Run,Santa Maria,New Jersey,Mexico,2005-10-09,2005-10-10,30543,2005-10-14,Samsung,590.29,5,354.85,Service,292.56,1032.22

Je suis ouvert à tous les outils Linux disponibles. Je voudrais garder python comme outil secondaire. Ceci n'est qu'une illustration. J'ai un milliard de fichiers.

Je voudrais également remplacer les fichiers en place. Je sais que je peux faire cela avec -i pour sed mais je ne sais pas pour awk.


0 commentaires

5 Réponses :


0
votes

Essayez le fichier sed -i '1 i \ any' .

sed est un remplacement

-i est à remplacer en place

1 indique la ligne 1, c'est-à-dire l'en-tête

i \ signifie préfixer

file est le nom de fichier ou le modèle correspondant à vos fichiers.


6 commentaires

Hey merci pour ta réponse. Je connais déjà l'utilisation de -i . C'est comme une chose secondaire pour moi. Je ne sais pas s'il existe un équivalent pour awk . L'objectif principal pour moi est de faire l'ajout dans le fichier. Btw, bienvenue à SO. :)


Tout comme GNU sed a -i , GNU awk a -i en place .


@EdMorton lorsque je fais / inplace dans ma page de manuel, aucun résultat n'est trouvé.


Alors vous ne cherchez pas dans la page de manuel pour GNU awk. Voir gnu.org/software/gawk/manual/gawk .html # Extension-Sample-Inpl‌ ace


@EdMorton Je pense que j'ai mawk au lieu de gawk


Si vous avez ou pouvez obtenir GNU sed, vous avez ou pouvez obtenir GNU awk et si vous faites sed -i 'script' alors vous utilisez GNU sed. Get gawk - il a une TONNE de fonctionnalités extrêmement utiles au-dessus de POSIX awk.



3
votes

En supposant qu'il n'y ait pas de noms de fichiers désagréables, quelque chose comme ça fonctionne:

find . -name '*.csv' -printf "%f\n" |
sed 's/.csv$//' |
xargs -I{} sed -i '1s/^/customer,/; 1!s/^/{},/' {}.csv

Je trouve d'abord tous les fichiers csv et j'imprime uniquement le nom de fichier.
Supprimez ensuite le suffixe .csv des fichiers.
Ensuite, je lance xargs, donc pour chaque fichier ...
... ajouter au début de la ligne client, si c'est la première ligne, sinon j'ajoute le nom de fichier sans .csv au début de la ligne. p >


0 commentaires

1
votes

Autre solution avec awk:

find . -name \*.csv -exec awk '{ gsub(".csv","",FILENAME); if (NR == 1) {print "customer," $0; next; } else print FILENAME (NF?",":"") $0} END { print ""; }' {} \;

si vous voulez une ligne vide avant le fichier suivant:

find . -name \*.csv -exec awk '{ gsub(".csv","",FILENAME); if (NR == 1) {print "customer," $0; next; } else print FILENAME (NF?",":"") $0}' {} \;

ce fichier de recherche avec l'extension csv et exécutez le script awk sur chacun.


0 commentaires

1
votes

Pour un seul fichier, vous pouvez faire

awk '(FNR==1){f=FILENAME+0; print "customer,",$0; next}
     {print f","$0 > (FILENAME".new") }' *.csv

Pour tous les fichiers CSV en une seule fois

awk '(FNR==1){f=FILENAME+0; print "customer,",$0; next}
     {print f","$0 }' input.csv > output.csv


0 commentaires

3
votes
$ tail -n +1 10000000.csv 10000001.csv
==> 10000000.csv <==
customer,first_name,middle_name,last_name,gender,email,phone_number,address,city,state,country,date_order_start,date_order_complete,invoice_number,invoice_date,item,item_price,quantity,cost,job_name,job_price,total_cost
10000000,Chae,Jesusa,Cummings,Female,deifier2040@live.com,775-861-8750,911 Hauser Pike,Moline,Georgia,Cameroon,2016-06-29,2016-07-16,36298,2016-07-17,Acer,493.86,14,354.77,Broken,123.68,898.13

==> 10000001.csv <==
customer,first_name,middle_name,last_name,gender,email,phone_number,address,city,state,country,date_order_start,date_order_complete,invoice_number,invoice_date,item,item_price,quantity,cost,job_name,job_price,total_cost
10000001,Fleta,Rosette,Hurley,Other,tobacconist1857@outlook.com,1-952-701-1210,35 Freelon Arcade,Beaverton,Rhode Island,Cayman Islands,2009-06-08,2009-06-29,39684,2009-07-01,NVIDIA GeForce GTX 980,474.31,16,395.79,Broken,157.53,1088.04
10000001,Bennett,Dennis,George,Male,dona1910@live.com,(980) 033-4131,505 Robert C Levy Arcade,Wellington,Louisiana,Mexico,2019-05-09,2019-05-19,37938,2019-05-21,8GB,187.67,16,205.77,Service,170.21,1007.85
10000001,Tommye,Pamula,Diaz,Other,dovelet1967@live.com,204.950.4445,1001 Canby Boulevard,Edinburg,Massachusetts,Gambia,2004-05-02,2004-05-24,31364,2004-05-26,Lenovo,137.21,13,193.63,Replacement,246.43,934.31
10000001,Albert,Jerrold,Cohen,Other,bolio2036@live.com,+1-(122)-459-8491,1181 Baden Avenue,Menomonee Falls,Texas,Tajikistan,2019-08-03,2019-08-12,37768,2019-08-15,Intel® Iris™ Graphics 6100,396.46,17,223.02,Service,118.53,960.27
10000001,Louetta,Collene,Best,Fluid,dinner1922@live.com,1-506-051-7050,923 Barry Viaduct,Laurel,Illinois,St. Barthélemy,2009-03-02,2009-03-06,39557,2009-03-07,AMD Radeon R9 M395X,133.9,11,198.49,Fix,178.54,1055.32
10000001,Kandace,Wesley,Diaz,Female,closterium1820@yahoo.com,+1-(777)-098-5414,341 Garlington Run,Santa Maria,New Jersey,Mexico,2005-10-09,2005-10-10,30543,2005-10-14,Samsung,590.29,5,354.85,Service,292.56,1032.22

5 commentaires

Salut, j'ai essayé votre solution. Fonctionne vraiment bien. Et c'est incroyablement plus rapide que sed. Pouvez-vous expliquer pourquoi cette solution est plus rapide que la solution (utilisant sed) que j'ai acceptée?


Apparemment, dans mon PC, j'ai GNU awk, mais dans ma VirtualBox j'ai mawk. C'est pourquoi je n'ai pas pu exécuter le inplace au départ.


Avec mon script, le shell démarre 1 processus et il opère sur tous les fichiers à la fois. Avec l'approche find + sed + xargs + sed, le shell démarre un nouveau processus pour chaque fichier d'entrée (ou peut-être chaque groupe de quelques fichiers d'entrée en fonction de la manière dont xargs décide de gérer les appels à sed), puis quelques autres - cela prend temps.


Je vous remercie. S'il vous plaît voir mon édition pour les résultats du test en utilisant votre script, dans mon autre question.


Pour la postérité, c'est cette autre question: unix.stackexchange.com/q/533626/133219