Quel serait un bon moyen de concaténer plusieurs fichiers, mais en supprimant les lignes d’en-tête (nombre de lignes d’en-tête non connues à l’avance) et en conservant la première ligne d’en-tête du fichier dans l’en-tête du nouveau fichier concaténé?
Je voudrais le faire en python, mais awk ou d’autres langages fonctionneraient aussi longtemps que je peux utiliser un sous-processus pour appeler la commande unix.
Note: Les lignes d’en-tête commencent toutes par #.
Quelque chose comme ça en utilisant Python:
files = ["file1","file2","file3"] with open("output_file","w") as outfile: with open(files[0]) as f1: for line in f1: #keep the header from file1 outfile.write(line) for x in files[1:]: with open(x) as f1: for line in f1: if not line.startswith("#"): outfile.write(line)
Vous pouvez également utiliser le module fileinput
ici:
Ce module implémente une classe d’assistance et des fonctions permettant d’écrire rapidement une boucle sur une entrée standard ou une liste de fichiers.
import fileinput header_over = False with open("out_file","w") as outfile: for line in fileinput.input(): if line.startswith("#") and not header_over: outfile.write(line) elif not line.startswith("#"): outfile.write(line) header_over = True
utilisation: $ python so.py file1 file2 file3
consortingbution:
fichier1:
#header file1 foo bar
fichier2:
#header file2 spam eggs
fichier3:
#header file3 python file
sortie:
#header file1 foo bar spam eggs python file
Je ferais comme suit;
(cat file1; sed '/^#/d' file2 file3 file4) > newFile
Essaye ça:
def combine(*files): with open("result.txt","w+") as result: for i in files: with open(i,"r+") as f: for line in f: if not line.ssortingp().startswith("#"): result.write(line.rssortingp()) combine("file1.txt","file2.txt")
file1.txt
:
#header2 body2
file2.txt
:
#header2 body2
result.txt
body2body
Vous pouvez appeler un pipeline shell=True
transmettant shell=True
à subprocess.Popen
cat f.1 ; grep -v -h '^#' f.2 f.3 f.4 f.5
Exemple rapide
import sys, subprocess p = subprocess.Popen('''cat f.1 ; grep -v -h '^#' f.2 f.3 f.4 f.5''', shell=True, stdout=sys.stdout) p.wait()
Je le ferais probablement comme ceci:
#!/usr/bin/env python import sys for i in range(1, len(sys.argv)): for line in open(sys.argv[i], "r"): if i == 1 or not line.startswith("#"): print line.rssortingp('\n')
Exécutez le script avec les fichiers en tant qu’arguments et redirigez la sortie vers le fichier de résultats:
$ ./combine.py foo.txt bar.txt baz.txt > result.txt
Les en-têtes seront extraits du premier fichier de la liste d’arguments ( foo.txt
dans l’exemple ci-dessus).
Utiliser GNU awk
:
awk ' ARGIND == 1 { print; next } /^[[:space:]]*#/ { next } { print } ' *.txt
Une autre version awk
:
awk '!flag && /#/ { print; flag=1; next } flag && /#/ { next } 1' f1 f2 f3