J'essaie de changer l'ordre des lignes dans un modèle spécifique. Travailler avec un fichier avec plusieurs lignes (ex. 99 lignes). Pour toutes les trois lignes, je voudrais que la deuxième ligne soit la troisième ligne et la troisième la deuxième ligne.
EXEMPLE.
1- Entrée:
gi_1234
My cat is blue.
I have a cat.
gi_5678
My dog is orange.
I also have a dog.
...
2- Sortie:
gi_1234
I have a cat.
My cat is blue.
gi_5678
I also have a dog.
My dog is orange.
...
linux
text-processing
command-line
Annick Raymond
la source
la source
NR%3 == 0 { print; print delay; delay=""} END { if(length(delay) != 0 ) { print delay }
.Autrement dit,
p
imprimez la ligne actuelle, récupérez la lignen
ext,h
ancienne, obtenez la lignen
extG
et la ligne maintenue (ajoutez-la à l'espace de motif) etp
imprimez cet espace de motif de 2 lignes avec les troisième et deuxième lignes permutées.la source
Une autre approche awk :
Le résultat:
(getline L2)>0 && (getline L3)>0
- extrait les 2 enregistrements suivants s'ils existentchaque 2e et 3e enregistrements sont respectivement affectés à
L2
etL3
variablesla source
line2
, etc.Utilisation
perl
et un court script:Le script traite l'ensemble du fichier, pour chaque ligne (stockée dans
$_
), il obtiendra les deux lignes suivantes ($l2
et$l3
) et les imprimera dans l'ordre demandé: ligne1, ligne3, ligne2.la source
Une façon pourrait être la suivante:
Alternativement,
Résultats
la source
Pourquoi ne pas simplement faire une boucle while? Sous forme développée:
En "format simple ligne":
Les sorties:
la source
Perl
L'idée ici est que nous utilisons l'opérateur modulo
%
avec une$.
variable de numéro de ligne , pour déterminer lequel est chaque premier, lequel est chaque seconde et lequel est chaque troisième ligne. Pour chaque 3ème ligne, le reste est 0, tandis que pour chaque 1ère et 2ème ligne, il aura des numéros correspondants.Tester:
Amélioration mineure
L'approche consistant à stocker la deuxième ligne dans une variable présente un défaut. Que faire si la dernière ligne est la "deuxième", c'est-à-dire que pour ce numéro de ligne, le reste est 2? Le code d'origine dans ma réponse et celle de DopeGhoti ne s'imprimera pas
My dog is orange
si nous omettons la dernière ligne. La solution pour cela dans les deux cas est d'utiliser unEND{}
bloc de code, avec la suppression de la variable temporaire après l'impression. En d'autres termes:et
De cette façon, le code fonctionnera pour un nombre arbitraire de lignes dans un fichier, pas seulement celles divisibles par 3.
Correctif supplémentaire pour le problème mentionné dans les commentaires
Dans le cas de awk, si la dernière ligne du fichier produit une sortie de 1 pour $. % 3, le code précédent a un problème de sortie de la nouvelle ligne vide à cause de l'impression inconditionnelle de
END{print delay}
, car laprint
fonction mentionnée dans les commentaires ajoute toujours la nouvelle ligne à la variable sur laquelle elle opère. En cas deperl
version, ce problème ne se produit pas, car avec la fonction-ne
drapeauxprint
n'ajoute pas la nouvelle ligne.Néanmoins, le correctif dans le cas d'awk est de rendre conditionnel, comme mentionné par Dope Ghoti dans les commentaires, est de vérifier la longueur de la variable temporaire. La version Perl du même correctif serait:
la source
awk
)NR%3 == 0 { print; print delay; delay=""} END { if(length(delay) != 0 ) { print delay }
.-ne
drapeaux ne génère pas de nouvelle ligne. Il s'imprime bien, mais c'est une chaîne nulle, pas de retour à la ligne. Néanmoins, j'ai ajouté la mention du problème et le même correctif dans ma réponse. Merci !Vigueur
Ne convient pas aux fichiers longs, mais toujours pratique si vous venez de modifier un fichier et que vous souhaitez, par exemple, réorganiser certaines strophes Yaml.
Enregistrez d'abord une macro:
Et puis répétez le nombre de fois souhaité:
Ou tout simplement par exemple
Explication:
la source
@q @q @q
, il est possible de le faire de cette façon3@q
- répétez trois fois.100@q
- répétez la macro 100 fois.Usage:
./shuffle_lines.awk input.txt
Vérifiez shebang
#!/usr/bin/awk -f
, car l'awk
emplacement peut différer sur votre système.la source