Odpowiedzi:
Używanie sed
do emulacji tac
:
sed '1!G;h;$!d' ${inputfile}
sed
jednowarstwowy. Zobacz „36. Odwróć kolejność wierszy (emuluj polecenie„ tac ”Unix).” w Famous Sed One-Liners wyjaśnił pełne wyjaśnienie tego, jak to działa.
sort
- istnieje szansa, że użyje pliku tymczasowego).
Z ed
:
ed -s infile <<IN
g/^/m0
,p
q
IN
Jeśli jesteś na BSD
/ OSX
(i miejmy nadzieję, że wkrótce na GNU
/ linux
zbyt jak to będzie POSIX ):
tail -r infile
awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' file.txt
przez awk one liner
awk 'a=$0RS a{}END{printf a}'
but your first
perl reverse <> `to najlepsza / najszybsza odpowiedź na stronie (dla mnie), 10 razy szybsza niż ta awk
odpowiedź (wszystkie ankresy awk są mniej więcej takie same, jeśli chodzi o czas)
awk '{a[NR]=$0} END {while (NR) print a[NR--]}'
Gdy poprosiłeś o zrobienie tego w bashu, oto rozwiązanie, które nie korzysta z awk, sed ani perla, tylko funkcję bash:
reverse ()
{
local line
if IFS= read -r line
then
reverse
printf '%s\n' "$line"
fi
}
Dane wyjściowe
echo 'a
b
c
d
' | reverse
jest
d
c
b
a
Zgodnie z oczekiwaniami.
Ale uwaga: wiersze są przechowywane w pamięci, po jednym wierszu w każdej rekurencyjnie nazywanej instancji funkcji. Ostrożnie z dużymi plikami.
Możesz przepuścić przez:
awk '{print NR" "$0}' | sort -k1 -n -r | sed 's/^[^ ]* //g'
Te awk
prefiksy każda linia z numerem linii a następnie po spacji. sort
Odwraca się kolejność linii sortując na pierwszym polu (numer linii) w odwrotnej kolejności, stylu numerycznej. I sed
usuwa numery linii.
Poniższy przykład pokazuje to w działaniu:
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'
Wyprowadza:
l
k
j
i
h
g
f
e
d
c
b
a
cat -n
zachowuje się bardzo podobnieawk '{print NR" "$0}'
W perlu:
cat <somefile> | perl -e 'while(<>) { push @a, $_; } foreach (reverse(@a)) { print; }'
perl -e 'print reverse<>'
perl -pe '$\=$_.$\}{'
)
reverse<)
jest szybki: dobrze! ale „naprawdę brzydka” jest bardzo wolna, gdy liczba linii rośnie. !! ....
-n
było zbyteczne, dzięki.
sort
).
Rozwiązanie tylko dla BASH
wczytaj plik do tablicy bash (jedna linia = jeden element tablicy) i wydrukuj tablicę w odwrotnej kolejności:
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=''
i, read -r
aby zapobiec wszelkim ucieczkom i końcowemu usuwaniu IFS przed zepsuciem go. Myślę, że mapfile ARRAY_NAME
wbudowane bash jest lepszym rozwiązaniem do wczytywania tablic.
Bash, z mapfile
wymienionymi w komentarzach do fiximan, a właściwie być może lepszą wersją:
# 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
}
Jego wydajność jest zasadniczo porównywalna z sed
rozwiązaniem i rośnie szybciej wraz ze spadkiem liczby żądanych linii.
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'
jak pokazano tutaj:
echo 'e
> f
> a
> c
> ' | nl | sort -nr | sed -r 's/^ *[0-9]+\t//'
Wynik:
c a f e
awk '{print NR" "$0}' | sort -nr