Je voudrais inverser l'ordre des lignes dans un fichier texte (ou stdin), en préservant le contenu de chaque ligne.
Donc, c'est-à-dire en commençant par:
foo
bar
baz
J'aimerais finir avec
baz
bar
foo
Existe-t-il un utilitaire de ligne de commande UNIX standard pour cela?
shell
unix
command-line
Scotty Allen
la source
la source
perl -e 'print reverse <>'
mais cela s'applique probablement aussi à d'autres méthodes).Réponses:
Queue BSD:
Référence: pages de manuel FreeBSD , NetBSD , OpenBSD et OS X.
la source
A noter également:
tac
(le, ahem, revers decat
). Une partie de coreutils .Retourner un fichier dans un autre
la source
brew install coreutils
(installegtac
par défaut).echo -n "abc\ndee" > test; tac test
.Il y a les astuces sed bien connues :
(Explication: ajouter une ligne non initiale pour conserver le tampon, permuter la ligne et conserver le tampon, imprimer la ligne à la fin)
Alternativement (avec une exécution plus rapide) à partir des uniformes awk :
Si vous ne vous en souvenez pas,
Sur un système avec des utilitaires GNU, les autres réponses sont plus simples, mais tout le monde n'est pas GNU / Linux ...
la source
tail -r
et tac.tac
devrait gérer des fichiers arbitraires volumineux qui ne tiennent pas en mémoire (la longueur de ligne est cependant toujours limitée). Il n'est pas clair si lased
solution fonctionne pour de tels fichiers.à la fin de votre commande mettez:
| tac
tac fait exactement ce que vous demandez, il "Ecrit chaque FICHIER sur la sortie standard, dernière ligne en premier".
tac est l'opposé de cat :-).
la source
tac
commande, ceci est utile pour les nouveaux utilisateurs qui pourraient finir par rechercher le même sujet.S'il vous arrive d'être en cours d'
vim
utilisationla source
exemple:
la source
Essayez
tac
, qui fonctionne sous Linux, et si cela ne fonctionne pas, utilisez-letail -r
, qui fonctionne sous BSD et OSX.la source
tac myfile.txt
- qu'est-ce qui me manque?tail -r
cas oùtac
n'est pas disponible.tac
n'est pas conforme à POSIX. Ni l'un ni l'autretail -r
. Toujours pas infaillible, mais cela améliore les chances de fonctionnement.tac
est disponible, mais manque de RAM et échange à mi-chemin en consommant un flux d'entrée géant. Il échoue, puistail -r
réussit à traiter le reste du flux, ce qui donne un résultat incorrect.brew install coreutils
et utilisezgtac
à la placetac
et si vous préférez, ajoutez tac comme aliasgtac
si, par exemple, vous vouliez un script shell qui l'utilisait sur plusieurs plates-formes (Linux, OSX)Essayez la commande suivante:
la source
sed 's/^[0-9]*://g'
nl
par défaut, ne numérotera pas les lignes vides. L'-ba
option est disponible sur certains systèmes, elle n'est pas universelle (HP / UX me vient à l'esprit, même si je ne le souhaite pas) alorsgrep -n
qu'elle numérotera toujours chaque ligne qui correspond à l'expression régulière (dans ce cas vide).cut -d: -f2-
Just Bash :) (4.0+)
la source
-nenenenenenene
et voyez pourquoi les gens recommandent de toujours utiliser à laprintf '%s\n'
place deecho
.La méthode la plus simple consiste à utiliser la
tac
commande.tac
estcat
l'inverse. Exemple:la source
J'aime vraiment la réponse " tail -r ", mais ma réponse gawk préférée est ....
la source
mawk
sur Ubuntu 14.04 LTS - fonctionne, il n'est donc pas spécifique à GNU awk. +1n++
peut être remplacé parNR
MODIFIER ce qui suit génère une liste de nombres triés au hasard de 1 à 10:
où les points sont remplacés par une commande réelle qui inverse la liste
tac
python: utilisation de [:: - 1] sur sys.stdin
la source
Pour une solution multi-OS (c'est-à-dire OSX, Linux) qui peut utiliser à l'
tac
intérieur d'un script shell, utilisez l'homebrew comme d'autres l'ont mentionné ci-dessus, alors alias tac comme ceci:Installer la lib
Pour MacOS
Pour Linux Debian
Ajoutez ensuite un alias
la source
Cela fonctionnera à la fois sur BSD et GNU.
la source
Si vous souhaitez modifier le fichier sur place, vous pouvez exécuter
Cela supprime la nécessité de créer un fichier temporaire, puis de supprimer ou renommer l'original et a le même résultat. Par exemple:
Sur la base de la réponse de l'éphémient , qui a fait presque, mais pas tout à fait, ce que je voulais.
la source
Il m'arrive que je souhaite obtenir efficacement les dernières
n
lignes d'un très gros fichier texte .La première chose que j'ai essayée est
tail -n 10000000 file.txt > ans.txt
, mais je l'ai trouvée très lente, cartail
elle doit chercher à l'emplacement puis recule pour imprimer les résultats.Quand je me rends compte, je passe à une autre solution:
tac file.txt | head -n 10000000 > ans.txt
. Cette fois, la position de recherche a juste besoin de se déplacer de la fin à l'emplacement souhaité et cela économise 50% de temps !Message à emporter:
À utiliser
tac file.txt | head -n n
si votretail
n'a pas l'-r
option.la source
Meilleure solution:
la source
Pour les utilisateurs Emacs:
C-x h
(sélectionnez l'ensemble du fichier), puisM-x reverse-region
. Fonctionne également pour sélectionner uniquement les pièces ou les lignes et les restaurer.la source
Je vois beaucoup d'idées intéressantes. Mais essayez mon idée. Canalisez votre texte dans ceci:
ce qui suppose que le caractère '~' n'est pas dans le fichier. Cela devrait fonctionner sur chaque shell UNIX remontant à 1961. Ou quelque chose comme ça.
la source
J'avais la même question, mais je voulais aussi que la première ligne (en-tête) reste au top. Je devais donc utiliser la puissance de awk
PS fonctionne également dans cygwin ou gitbash
la source
1\n20\n19...2\n
plutôt que20\n19...\2\n1\n
.Vous pouvez le faire avec
vim
stdin
etstdout
. Vous pouvez également utiliserex
pour être conforme à POSIX .vim
est juste le mode visuel pourex
. En fait, vous pouvez utiliserex
avecvim -e
ouvim -E
(ex
mode amélioré ).vim
est utile parce que contrairement à des outils commesed
celui-ci, le fichiersed
est mis en mémoire tampon pour l'édition, tandis que est utilisé pour les flux. Vous pourrez peut-être utiliserawk
, mais vous devrez tout mettre manuellement en mémoire tampon dans une variable.L'idée est de faire ce qui suit:
g/^/m0
. Cela signifie globalement, pour chaque ligneg
; correspond au début de la ligne, qui correspond à tout^
; déplacez-le après l'adresse 0, qui est la ligne 1m0
.%p
. Cela signifie pour la gamme de toutes les lignes%
; imprimer la lignep
.q!
. Cela signifie quitterq
; avec force!
.Comment rendre cela réutilisable
J'utilise un script que j'appelle
ved
(comme l'éditeur vimsed
) pour utiliser vim pour éditerstdin
. Ajoutez ceci à un fichier appeléved
dans votre chemin:J'utilise une
+
commande au lieu de+'%p' +'q!'
, car vim vous limite à 10 commandes. Leur fusion permet donc"$@"
d'avoir 9+
commandes au lieu de 8.Ensuite, vous pouvez faire:
Si vous n'avez pas vim 8, mettez-le à la
ved
place:la source
ou
ou
la source
queue -r fonctionne dans la plupart des systèmes Linux et MacOS
seq 1 20 | queue -r
la source
ou
la source
sort -r
ne fonctionne que si l'entrée est déjà triée, ce qui n'est pas le cas ici.rev
inverse les caractères par ligne mais garde l'ordre des lignes intact, ce qui n'est pas non plus ce que Scotty a demandé. Donc, cette réponse n'est en fait pas du tout une réponse.