Jawaban:
Menggunakan seduntuk meniru tac:
sed '1!G;h;$!d' ${inputfile}
sedone-liner yang terkenal . Lihat "36. Membalik urutan baris (meniru" tac "perintah Unix)." dalam Famous Sed One-Liners Dijelaskan untuk penjelasan lengkap tentang cara kerjanya.
sort- ada kemungkinan itu akan menggunakan file sementara).
awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' file.txt
via awk satu liners
awk 'a=$0RS a{}END{printf a}'
but your first perl membalikkan <> `itu jawaban terbaik / tercepat pada halaman (untuk saya), pada 10 kali lebih cepat dari awkjawaban ini (semua awk anseres hampir sama,
awk '{a[NR]=$0} END {while (NR) print a[NR--]}'
Saat Anda diminta untuk melakukannya di bash, berikut adalah solusi yang tidak menggunakan awk, sed atau perl, hanya fungsi bash:
reverse ()
{
local line
if IFS= read -r line
then
reverse
printf '%s\n' "$line"
fi
}
Output dari
echo 'a
b
c
d
' | reverse
aku s
d
c
b
a
Seperti yang diharapkan.
Tetapi berhati-hatilah bahwa garis-garis disimpan dalam memori, satu baris di masing-masing secara rekursif disebut instance dari fungsi. Jadi hati-hati dengan file besar.
Anda dapat menyalurkan melalui:
awk '{print NR" "$0}' | sort -k1 -n -r | sed 's/^[^ ]* //g'
The awkprefiks setiap baris dengan nomor baris diikuti dengan spasi. The sortmembalikkan urutan garis dengan mensortir field pertama (nomor baris) dalam urutan terbalik, gaya numerik. Dan sedstrip dari nomor baris.
Contoh berikut menunjukkan ini dalam tindakan:
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'
Ini menghasilkan:
l
k
j
i
h
g
f
e
d
c
b
a
cat -nbertindak sepertiawk '{print NR" "$0}'
Dalam perl:
cat <somefile> | perl -e 'while(<>) { push @a, $_; } foreach (reverse(@a)) { print; }'
perl -e 'print reverse<>'
perl -pe '$\=$_.$\}{')
reverse<)cepat: bagus! tetapi yang "benar-benar jelek" sangat lambat karena jumlah garis meningkat. !! ....
-nitu berlebihan di sana, terima kasih.
sort).
Solusi khusus BASH
baca file menjadi bash array (satu baris = satu elemen array) dan cetak array dalam urutan terbalik:
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=''dan read -runtuk mencegah semua jenis lolos dan tertinggal penghapusan IFS dari mengacaukannya. Saya pikir bash mapfile ARRAY_NAMEbuiltin adalah solusi yang lebih baik untuk membaca array.
Bash, dengan mapfiledisebutkan dalam komentar untuk fiximan, dan sebenarnya versi yang mungkin lebih baik:
# 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
}
Kinerjanya pada dasarnya sebanding dengan sedsolusi, dan semakin cepat karena jumlah baris yang diminta berkurang.
Simple do this with your file to sort the data in reverse order, and it should be unique.
sed -n '1j; 1d; G; h; $ p'
seperti yang ditunjukkan di sini:
echo 'e
> f
> a
> c
> ' | nl | sort -nr | sed -r 's/^ *[0-9]+\t//'
Hasil:
c a f e