Ce problème pourrait en fait être plus facile à résoudre ed, car il s'agit essentiellement d'un éditeur de texte scriptable, plutôt que d'un processeur de flux. En utilisant ed, vous n'avez pas à enregistrer toutes les lignes du fichier dans un tableau, par exemple, car il le fait déjà pour vous.
# Create test file
~> printf "%s\n" aaaaaa bbbbbb cccccc dddddd eeeeee >test.txt
~> cat test.txt
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
# Use ed to open the file, move the last line after the first, save, and quit
~> printf "%s\n" '$m1' wq | ed test.txt
35
35
~> cat test.txt
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
sed '$x;1!H;1p;$!d;x;s/\n//
' <<\IN
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN
... qui Hvieillira chaque ligne qui n'est !pas la première, et la première qu'elle pimprime. Sur la $dernière ligne, il xmodifie les espaces d'attente et de motif avant de faire l' Hancien - qui ajoute les lignes enregistrées à la dernière ligne - puis dsupprime de la sortie toutes les lignes qui !ne sont pas les $dernières.
Sur la $dernière ligne, il xmodifie à nouveau les espaces, s///remplace le premier \ncaractère de ligne électronique - qui prend en charge le supplément ajouté sur la ligne 2 - puis imprime automatiquement le lot.
PRODUCTION:
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
sans utiliser le tampon Hold:
cat <<\IN >infile
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN
... juste pour enregistrer votre exemple dans un fichier réel ...
sed '1p;$!d;r infile' <infile | sed '3d;$d'
Redirigeant <infileaux premiers sed« s stdin, qui ne prints la première ligne avant deleting de sortie toutes les lignes qui ne sont !pas la $dernière. La dernière ligne est autoprinted, mais il est aussi la seule ligne sur laquelle la dernière commande est exécutée - qui est à read sur l'ensemble de infilenouveau à stdout. Tout cela passe par le |tuyau vers le second sedqui n'a alors qu'à dsupprimer de sa sortie ses troisième et dernière lignes d'entrée pour terminer la réorganisation.
Vous stockez chaque ligne dans le atableau, puis imprimez le tableau dans l'ordre souhaité (1ère ligne, dernière ( NR) et de 2 à l'avant-dernière.
En utilisant une combinaison tête / queue et sed:
~$ head -1 f;tail -1 f;sed '1d;$d' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
Imprimez la première ligne, la dernière et avec sed supprimez la 1ère et la dernière.
Avec sed uniquement, je n'ai pu trouver que cette commande. Je suis sûr qu'il existe de meilleures façons:
~$ sed '${p;x;s/^\n//;p};2,${H;d}' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
S'il s'agit de la première ligne, imprimez-la (par défaut).
À partir de la deuxième ligne, placez-le dans le tampon de maintien ( H) et supprimez-le de l'espace de motif ( d). Et si c'est la dernière ligne, imprimez-la ( p), puis récupérez le tampon de maintien ( x), supprimez la ligne vide ( s/^\n//) et imprimez-la ( p).
awk
solutions, êtes-vous un grandsed
fan ou peut-être avez-vous écritsed
? ;-)awk
- je n'ai jamais essayé. peut-être un jour ...Une approche naïve avec awk:
Vous stockez chaque ligne dans le
a
tableau, puis imprimez le tableau dans l'ordre souhaité (1ère ligne, dernière (NR
) et de 2 à l'avant-dernière.En utilisant une combinaison tête / queue et sed:
Imprimez la première ligne, la dernière et avec sed supprimez la 1ère et la dernière.
Avec sed uniquement, je n'ai pu trouver que cette commande. Je suis sûr qu'il existe de meilleures façons:
S'il s'agit de la première ligne, imprimez-la (par défaut).
À partir de la deuxième ligne, placez-le dans le tampon de maintien (
H
) et supprimez-le de l'espace de motif (d
). Et si c'est la dernière ligne, imprimez-la (p
), puis récupérez le tampon de maintien (x
), supprimez la ligne vide (s/^\n//
) et imprimez-la (p
).la source
sed
pièce serait quelque chose commehead -n -1 f | tail -n +2
.-1
syntaxehead
n'est pas portable.Avec perl:
Avec awk:
PRODUCTION
la source