Réponses:
Utilisation sed
pour émuler tac
:
sed '1!G;h;$!d' ${inputfile}
sed
monoplace. 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
/ linux
aussi 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 awk
ré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 awk
préfixes de chaque ligne avec le numéro de ligne suivi d'un espace. L' sort
inverse l'ordre des lignes en triant le premier champ (numéro de ligne) dans l'ordre inverse, style numérique. Et les sed
bandes 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 -n
agit 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 -r
pour empêcher toutes sortes de fuites et de retrait IFS de fuite de le visser. Je pense que le bash mapfile ARRAY_NAME
builtin est une meilleure solution pour lire dans les tableaux.
Bash, avec mapfile
mentionné 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 sed
solution 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