Réponses:
Utilisation sedpour émuler tac:
sed '1!G;h;$!d' ${inputfile}
sedmonoplace. Voir "36. Ordre inverse des lignes (émuler la commande" tac "Unix)." dans Famous Sed One-Liners Explained pour une explication complète de son fonctionnement.
sort- il y a une chance qu'il utilise un fichier temporaire).
Avec ed:
ed -s infile <<IN
g/^/m0
,p
q
IN
Si vous êtes sur BSD/ OSX(et si tout va bien bientôt sur GNU/ linuxaussi car ce sera POSIX ):
tail -r infile
awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' file.txt
via awk one liners
awk 'a=$0RS a{}END{printf a}'
but your first perl reverse <> `c'est la meilleure / la plus rapide réponse sur la page (pour moi), à 10 fois plus rapide que cette awkréponse (tous les awk anseres sont à peu près les mêmes, dans le temps)
awk '{a[NR]=$0} END {while (NR) print a[NR--]}'
Comme vous l'avez demandé en bash, voici une solution qui n'utilise pas awk, sed ou perl, juste une fonction bash:
reverse ()
{
local line
if IFS= read -r line
then
reverse
printf '%s\n' "$line"
fi
}
La sortie de
echo 'a
b
c
d
' | reverse
est
d
c
b
a
Comme prévu.
Mais attention, les lignes sont stockées en mémoire, une ligne dans chaque instance appelée récursivement de la fonction. Si prudent avec les gros fichiers.
Vous pouvez le diriger à travers:
awk '{print NR" "$0}' | sort -k1 -n -r | sed 's/^[^ ]* //g'
Les awkpréfixes de chaque ligne avec le numéro de ligne suivi d'un espace. L' sortinverse l'ordre des lignes en triant le premier champ (numéro de ligne) dans l'ordre inverse, style numérique. Et les sedbandes des numéros de ligne.
L'exemple suivant montre cela en action:
pax$ echo 'a
b
c
d
e
f
g
h
i
j
k
l' | awk '{print NR" "$0}' | sort -k1 -n -r | sed 's/^[^ ]* //g'
Il génère:
l
k
j
i
h
g
f
e
d
c
b
a
cat -nagit commeawk '{print NR" "$0}'
En perl:
cat <somefile> | perl -e 'while(<>) { push @a, $_; } foreach (reverse(@a)) { print; }'
perl -e 'print reverse<>'
perl -pe '$\=$_.$\}{')
reverse<)c'est rapide: bon! mais le "vraiment moche" est extrêmement lent car le nombre de lignes augmente. !! ....
-nétait superflu là-bas, merci.
sort).
Solution BASH uniquement
lire le fichier dans le tableau bash (une ligne = un élément du tableau) et imprimer le tableau dans l'ordre inverse:
i=0
while read line[$i] ; do
i=$(($i+1))
done < FILE
for (( i=${#line[@]}-1 ; i>=0 ; i-- )) ; do
echo ${line[$i]}
done
while..read.
IFS=''et read -rpour empêcher toutes sortes de fuites et de retrait IFS de fuite de le visser. Je pense que le bash mapfile ARRAY_NAMEbuiltin est une meilleure solution pour lire dans les tableaux.
Bash, avec mapfilementionné dans les commentaires de fiximan, et en fait une version peut-être meilleure:
# last [LINES=50]
_last_flush(){ BUF=("${BUF[@]:$(($1-LINES)):$1}"); } # flush the lines, can be slow.
last(){
local LINES="${1:-10}" BUF
((LINES)) || return 2
mapfile -C _last_flush -c $(( (LINES<5000) ? 5000 : LINES+5 )) BUF
BUF=("${BUF[@]}") # Make sure the array subscripts make sence, can be slow.
((LINES="${#BUF[@]}" > LINES ? LINES : "${#BUF[@]}"))
for ((i="${#BUF[@]}"; i>"${#BUF[@]}"-LINES; i--)); do echo -n "${BUF[i]}"; done
}
Ses performances sont fondamentalement comparables à la sedsolution et deviennent plus rapides à mesure que le nombre de lignes demandées diminue.
Simple do this with your file to sort the data in reverse order, and it should be unique.
sed -n '1h; 1d; G; h; $ p'
comme indiqué ici:
echo 'e
> f
> a
> c
> ' | nl | sort -nr | sed -r 's/^ *[0-9]+\t//'
Résultat:
c a f e