Il y a des lignes spécifiques que je veux supprimer d'un fichier. Disons que c'est la ligne 20-37, puis la ligne 45. Comment pourrais-je faire cela sans préciser le contenu de ces lignes?
Il y a des lignes spécifiques que je veux supprimer d'un fichier. Disons que c'est la ligne 20-37, puis la ligne 45. Comment pourrais-je faire cela sans préciser le contenu de ces lignes?
Réponses:
Avec sed
, comme ça:
sed '20,37d; 45d' < input.txt > output.txt
Si vous vouliez le faire sur place:
sed --in-place '20,37d; 45d' file.txt
This option specifies that files are to be edited in-place. GNU
sed 'le fait en créant un fichier temporaire et envoyer la sortie vers ce fichier plutôt que vers la sortie standard. »... Je ne connais pas d'autre« sed »mais la logistique de la mise à jour« en place »avec un éditeur de flux ne« calcule »pas :)
Si le fichier tient confortablement en mémoire, vous pouvez également l'utiliser ed
.
Les commandes sont assez similaires à celle sed
ci-dessus avec une différence notable : vous devez passer la liste des numéros / plages de lignes à supprimer dans l'ordre décroissant (de la ligne / plage la plus élevée à la plus basse). La raison en est que lorsque vous supprimez / insérez / divisez / joignez des lignes avec ed
, le tampon de texte est mis à jour après chaque sous-commande, donc si vous supprimez certaines lignes, les autres lignes suivantes ne seront plus à la même position dans le tampon lorsque le la sous-commande suivante est exécutée. Il faut donc recommencer à l'envers 1 .
Modification sur place :
ed -s in_file <<IN
45d
20,37d
w
q
IN
ou
ed -s in_file <<< $'45d\n20,37d\nw\nq\n'
ou
printf '%s\n' 45d 20,37d w q | ed -s in_file
Remplacez w
rite par ,p
rint si vous souhaitez imprimer la sortie résultante au lieu d'écrire dans un fichier. Si vous souhaitez conserver le fichier d'origine intact et écrire dans un autre fichier, vous pouvez passer le nouveau nom de fichier à la w
sous-commande rite:
ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN
1
À moins que vous ne vouliez calculer les nouveaux numéros de ligne après chaque d
suppression, ce qui est assez trivial pour ce cas particulier (après la suppression des lignes 20 à 37, soit 18 lignes, la ligne 45 devient la ligne 27) afin que vous puissiez exécuter:
ed -s in_file <<IN
20,37d
27d
w
q
IN
Cependant, si vous devez supprimer plusieurs numéros de ligne / plages, travailler en arrière est une évidence.
q
commande est-elle utile à la fin? Je suppose que ça sort de toute façon.
Il suffit de le lire en mémoire, de le modifier, puis de le réécrire. Vous pouvez faire quelque chose comme
filename = "foo"
f = open(filename, 'r+')
linenums = [1, 3]
s = [y for x, y in enumerate(f) if x not in [line-1 for line in linenums]]
f.seek(0)
f.write(''.join(s))
f.truncate(f.tell())
f.close()
Testé avec un fichier 5 lignes. Crédits à http://pleac.sourceforge.net/pleac_python/fileaccess.html , voir la section "Modification d'un fichier sur place sans fichier temporaire". Voir aussi /programming/125703/how-do-i-modify-a-text-file-in-python
Quelques notes:
On pourrait d'abord tronquer le fichier, puis y écrire, plutôt qu'écrire, puis tronquer, comme ci-dessus. Cependant, je ne connais pas d'indicateur Python qui permette de lire, puis de faire une écriture tronquée. Mais peut-être que je manque quelque chose, car le document n'est pas très clair. Ce qui m'amène à
Parfois, les documents Python sont vraiment nuls. Voir http://docs.python.org/library/functions.html#open
Les modes 'r +', 'w +' et 'a +' ouvrent le fichier pour la mise à jour (notez que 'w +' tronque le fichier).
Est-ce que cela signifie quelque chose pour vous? Qu'est-ce qui est "ouvert à la mise à jour"?
Je ne sais pas si faire cela en python par opposition à quelque chose d'unixy comme l'éditeur de flux est mieux. C'est peut-être plus portable, mais je ne sais pas à quel point sed est portable. Je viens de l'écrire comme ça parce que je suis plus à l'aise avec la programmation de bas niveau que d'utiliser les outils Unix classiques, qui sont bons s'ils font exactement ce que vous voulez, mais (je pense) sont généralement moins flexibles.
Cette approche (manipulation du fichier en mémoire) échange la mémoire contre de l'espace disque. Cela devrait fonctionner correctement sur les machines avec quelques Go de mémoire pour des fichiers jusqu'à quelques centaines de Mb. Python ne gère pas les chaînes très efficacement, donc le passage au C / C ++ par exemple augmenterait légèrement les performances et réduirait considérablement l'utilisation de la mémoire.
Vous pouvez utiliser Vim en mode Ex:
ex -sc '20,37d|45d|x' file
d
supprimer
x
sauver et fermer