Je dois prendre une liste (charges) d'adresses IP dans ce format:
134.27.128.0
111.245.48.0
109.21.244.0
et les transformer en ce format avec un tuyau entre les deux (IP composées)
134.27.128.0 | 111.245.48.0 | 109.21.244.0 | 103.22.200.0/22
Je pense que c'est une commande find and replace comme sed
mais je ne peux pas la faire fonctionner.
shell
text-processing
uselesslinuxman
la source
la source
tr
insérer des nouvelles lignes dans des|
tuyaux? Comme<ipfile tr \\n \| >outfile
?|
nécessaire?<
. Alors<mydoc tr \\n \| >mydoc2
. Mais cela ne vous donnera pas les espaces. Pour ceux-là, la solution la plus rapide estpaste -d' | ' mydoc /dev/null /dev/null >mydoc2
paste
écrit des lignes correspondant à chaque fichier. Sans-s
, vous récupérerez le nombre de lignes que vous avez dans le fichier.Réponses:
Avec sed, basé sur Célèbres Sed one-liners Expliqué Partie I: : 39. Append une ligne à l'autre si elle se termine par une barre oblique inverse « \ » (sauf ici on fait abstraction de la part de la barre oblique inverse, et remplaçons les
\n
nouvelles lignes avec la|
séparateur requis ):devrait produire en
mydoc2
la source
sed 'H;1h;$!d;x;s/\n/ | /g'
est linéaire.sed
espace modèle de 8K; c'est beaucoup moins de 16 millions.J'étais curieux de voir comment certains d'entre eux (+ quelques alternatives) fonctionnent en termes de vitesse avec un fichier assez volumineux (
163MiB
unIP
par ligne, ~ 13 millions de lignes):Résultats (avec
sync; echo 3 > /proc/sys/vm/drop_caches
après chaque commande; j'ai répété les tests - dans l'ordre inverse - après quelques heures mais les différences étaient négligeables; notez également que j'utilisegnu sed
):tournevis :
très lent. Avorté après deux minutes d'attente ... donc pas de résultat pour celui-ci.
cuonglm :
mikeserv :
jthill :
Avinash Raj :
et
val0x00ff :
ce qui signifie
184.321s
. Sans surprise, c'est 200 fois plus lent que la solution de mikeserv .Voici d'autres façons d'
utiliser awk:
perl:
xargs:
une combinaison tête + pâte + tr + chat:
Si vous en avez
GNU coreutils
et si votre liste d'adresses IP n'est pas vraiment énorme (disons jusqu'à 50000 adresses IP), vous pouvez également le faire avecpr
:où
par exemple pour un fichier de 6 lignes:
la commande:
les sorties:
la source
while ... read
boucle? Je suis curieux de voir à quoi se traduit 163kread()
etwrite()
appels dans une référence. Excellente réponse, au fait.sed
semble avoir amélioré sa position à ce moment-là (et n'a probablement apporté que très peu de modifications à son moteur d'expression régulière), maisgrep
semble avoir considérablement pris du retard dans ses performances (en particulier pour les lignes plus longues) ? Je me demande si lesperl
ajouts à son moteur ont une incidence sur ces résultats ... C'est aussi soigné quidash
n'est pas abyssal . L'bash
ici serait probablement beaucoup plus lent avec le courantIFS=
ajouté.lex
correctement.Vous pouvez utiliser awk :
ORS=' | '
définissez le séparateur d'enregistrement de sortie sur au' | '
lieu de la nouvelle ligne.ou éditez sur place avec
perl
:la source
paste
marche. très appréciée.paste
solution est la plus rapide.ORS=""
intérieur duEND
bloc parORS="\n"
pour qu'il le fasse.J'ai donc eu tout faux - et cette question m'a beaucoup appris
paste
. Comme cuonglm le note correctement, à moins que vous ne disposiez d'paste
un fichier in en-s
erial, vous finirez toujours avec la dernière ligne\n
électronique de votre liste d'infile ajoutée à la sortie telle qu'elle est écrite. Je me trompais en croyant que lepaste -s
comportement était son mode par défaut - et c'est une idée fausse qui, apparemment,busybox
paste
était heureuse de renforcer. La commande suivante fonctionne comme annoncé avecbusybox
:Cependant, cela ne fonctionne pas selon les spécifications. Une mise en œuvre correctement
paste
ajouterait toujours une ligne de\n
queue pour chaque séquence écrite. Pourtant, ce n'est pas grave après tout:la source
pr
à l'esprit, mais apparemment, il s'essouffle avec d'énormes fichiers d'entrée, donc je ne pouvais pas réellement tester la vitesse, mais avec des fichiers de longueur raisonnable, cela fonctionne bien. Votre solution est de loin la plus rapide (pas de surprise -paste
c'est vraiment rapide), voir mon article.one-liner avec tr et sed:
la source
Utiliser
vim
:Explication:
-n
désactiver le fichier d'échange-u NONE
est utilisé pour ignorer toutes les initialisations.-c {command}
exécuter des commandes après la lecture du fichier.1,$-1s/\n/ | /g
ests/\n/ | /g
(remplacer la nouvelle ligne par l'espace du tube espace) pour la plage1,$-1s
(1ère ligne à la dernière ligne - 1)wq!
forcer l'écriture et quitterRemarque:
Selon la taille réelle de votre fichier, cela peut être une mauvaise idée.
la source
Par python.
avant
print
était très important.la source
En voici un autre utilisant
xxd
la source
Par souci d'exhaustivité, voici une autre
awk
solution basée sur celle-ci, celle-ci n'utilise pas duORS
tout:Pour une explication, voir mon article sur /unix//a/338121/117599 .
la source