Antworten:
Verwenden sed
, um zu emulieren tac
:
sed '1!G;h;$!d' ${inputfile}
sed
Einzeiler. Siehe "36. Umgekehrte Reihenfolge der Zeilen (Unix-Befehl" tac "emulieren)." in Famous Sed One-Liners Erklärt für eine vollständige Erklärung, wie es funktioniert.
sort
- es besteht die Möglichkeit, dass eine temporäre Datei verwendet wird).
Mit ed
:
ed -s infile <<IN
g/^/m0
,p
q
IN
Wenn Sie auf BSD
/ sind OSX
(und hoffentlich bald auch auf GNU
/ linux
wie es POSIX sein wird ):
tail -r infile
awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' file.txt
über awk one liner
awk 'a=$0RS a{}END{printf a}'
but your first
perl reverse <> `es ist die beste / schnellste Antwort auf der Seite (für mich), 10-mal schneller als diese awk
Antwort (alle awk Anseres sind ungefähr gleich, zeitlich)
awk '{a[NR]=$0} END {while (NR) print a[NR--]}'
Hier ist eine Lösung, die awk, sed oder perl nicht verwendet, sondern nur eine bash-Funktion:
reverse ()
{
local line
if IFS= read -r line
then
reverse
printf '%s\n' "$line"
fi
}
Die Ausgabe von
echo 'a
b
c
d
' | reverse
ist
d
c
b
a
Wie erwartet.
Achten Sie jedoch darauf, dass die Zeilen im Speicher gespeichert sind, eine Zeile in jeder rekursiv aufgerufenen Instanz der Funktion. So vorsichtig mit großen Dateien.
Sie können es durchpfeifen:
awk '{print NR" "$0}' | sort -k1 -n -r | sed 's/^[^ ]* //g'
Das awk
Präfix jeder Zeile enthält die Zeilennummer, gefolgt von einem Leerzeichen. Die sort
Reihenfolge der Zeilen wird umgekehrt, indem das erste Feld (Zeilennummer) in umgekehrter Reihenfolge im numerischen Stil sortiert wird. Und dersed
Streifen von den Zeilennummern.
Das folgende Beispiel zeigt dies in Aktion:
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'
Es gibt aus:
l
k
j
i
h
g
f
e
d
c
b
a
cat -n
wirkt ähnlich wieawk '{print NR" "$0}'
In Perl:
cat <somefile> | perl -e 'while(<>) { push @a, $_; } foreach (reverse(@a)) { print; }'
perl -e 'print reverse<>'
perl -pe '$\=$_.$\}{'
)
reverse<)
ist schnell: gut! Aber die "wirklich hässliche" ist extrem langsam, da die Anzahl der Zeilen erhöht. !! ....
-n
war da überflüssig, danke.
sort
).
Nur-BASH-Lösung
Lies die Datei in das Bash-Array (eine Zeile = ein Element des Arrays) und drucke das Array in umgekehrter Reihenfolge aus:
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=''
und read -r
, um zu verhindern, dass alle Arten von Ausbrüchen und nachfolgende IFS-Entfernung es vermasseln. Ich denke, dass die Bash- mapfile ARRAY_NAME
Funktion eine bessere Lösung für das Einlesen in Arrays ist.
Bash, mit mapfile
in Kommentaren erwähntem Fiximan, und eigentlich eine möglicherweise bessere Version:
# 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
}
Die Leistung ist im Wesentlichen mit der der sed
Lösung vergleichbar und wird mit abnehmender Anzahl der angeforderten Leitungen schneller.
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'
wie hier gezeigt:
echo 'e
> f
> a
> c
> ' | nl | sort -nr | sed -r 's/^ *[0-9]+\t//'
Ergebnis:
c a f e