J'ai des fichiers qui ont été générés par un programme qui n'a pas mis de nouvelles lignes à la fin des enregistrements. Je veux mettre des retours à la ligne entre les enregistrements, et je peux le faire avec un simple script sed:
sed -e 's/}{/}\n{/g'
Le problème est que les fichiers d'entrée ont une taille de plusieurs gigaoctets, et donc les lignes d'entrée à sed ont une longueur de plusieurs Go. sed essaie de garder une ligne en mémoire, ce qui ne fonctionne pas dans ce cas. J'ai essayé l' --unbuffered
option, mais cela semblait simplement la ralentir et ne lui permettait pas de se terminer correctement.
tr
pour traduire}
en\n
puis utilisersed
pour ajouter un}
à la fin de chaque ligne? Comme ceci:tr '}' '\n' < your_file.txt| sed 's/$/}/'
printf "\n" >> file
}{
répétition jusqu'à ce qu'il soit de plusieurs gigaoctets suffirait.dd if=file cbs=80 conv=unblock
serait le cas - mais c'est rarement aussi simple.Réponses:
Vous pouvez utiliser un autre outil qui vous permet de définir le séparateur d'enregistrement d'entrée. Par exemple
Perl
La variable spéciale
$/
est le séparateur d'enregistrement d'entrée. Le}{
définir pour définir les lignes se terminant par}{
. De cette façon, vous pouvez réaliser ce que vous voulez sans lire le tout dans la mémoire.mawk ou gawk
C'est la même idée.
RS="}{"
définit le séparateur d'enregistrement sur}{
et ensuite vous imprimez}
, une nouvelle ligne,{
(sauf pour le premier enregistrement) et l'enregistrement en cours.la source
Perl à la rescousse:
Le réglage
$/
sur\1024
lira le fichier par blocs de 1024 octets. La$closing
variable gère le cas où un morceau se termine}
et le suivant commence par{
.la source
Tu devrais faire:
C'est probablement la solution la plus efficace.
Cela met un
{}
pour protéger toutes les données de fin possibles. Avec untr
processus de plus , vous pouvez échanger cela et faire une ligne vierge en tête du premier{
champ. Comme...Ainsi, le premier, avec les données d'exemple de don, fait:
... et le second fait ...
Il n'y a pas de nouvelle ligne de fin pour le deuxième exemple - bien qu'il y en ait une pour le premier.
la source
Un
sed
utilitaire de type binaire appelébbe
Je trouve qu'il est plus facile de conserver une syntaxe de type sed dans ce cas.
Je beaucoup préfère utiliser l'
bbe
utilitaire (disponible via votre {uni, Linu} l'installation du package de x, éqapt-get
). Ou ici, si vous faites partie de la foule git, bien que je n'ai pas personnellement vérifié ce lien particulier.1. Il prend en charge l'
s/before/after/
idiomeIl s'agit d'un "éditeur de blocs binaires", qui prend en charge les opérations de type sed (entre autres). Cela inclut l'
s/before/after/
idiome de substitution super commun dont vous avez besoin. Notez, car il n'y a pas de lignes en soi dubbe
point de vue de, il n'y a pas de "g global" à la fin de la commande.Comme test rapide (notez le requis
-e
):produit:
2. Dans votre cas spécifique de
}{
la}\n{
conversionDonc, si nous avions un fichier volumineux rempli d'un million de numéros dans (disons) le format
{1}{2}{3}
...{1000000}
sans retour chariot, nous pourrions échanger facilement}{
avec}\n{
, et avoir tous les numéros un par ligne.Ce serait avec cette
bbe
commande:Comme testé dans cette boucle zsh, dont nous saisissons juste la queue de:
Ce qui produirait ceci:
(sans retour de chariot arrière bien sûr.)
la source