Yanıtlar:
sed
Taklit etmek için kullanma tac
:
sed '1!G;h;$!d' ${inputfile}
sed
bir tek astar. Bkz. "36. Satırların ters sıralaması (" tac "Unix komutunu taklit edin)." içinde Ünlü Sed Tek Gömlekleri Açıklaması nasıl çalıştığını tam bir açıklama için.
sort
- geçici bir dosya kullanması ihtimali vardır).
İle ed
:
ed -s infile <<IN
g/^/m0
,p
q
IN
Üzerinde iseniz BSD
/ OSX
(ve umarım yakında üzerinde GNU
/ linux
çok olarak o POSIX olacaktır ):
tail -r infile
awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' file.txt
yoluyla bir gömlekleri awk
awk 'a=$0RS a{}END{printf a}'
but your first
perl reverse <> `sayfadaki en iyi / en hızlı cevap (benim için), bu awk
cevaptan 10 kat daha hızlı (tüm awk anseres aynı, zaman dilimi aynı)
awk '{a[NR]=$0} END {while (NR) print a[NR--]}'
Bunu bash yapmak istedi, işte awk, sed veya perl, sadece bash işlevini kullanmayan bir çözüm:
reverse ()
{
local line
if IFS= read -r line
then
reverse
printf '%s\n' "$line"
fi
}
Çıktısı
echo 'a
b
c
d
' | reverse
olduğu
d
c
b
a
Beklenildiği gibi.
Fakat satırların bellekte saklandığından ve fonksiyonun tekrarlanan adıyla her birinde bir satır olduğundan emin olun. Büyük dosyalara çok dikkat et.
Boru ile yapabilirsiniz:
awk '{print NR" "$0}' | sort -k1 -n -r | sed 's/^[^ ]* //g'
awk
Her satırın satır numarası ve ardından boşluk bulunan ön ekler. sort
Ters, sayısal bir tarzda ilk alan (satır sayısı) sıralayarak hatları sırasını tersine çevirir. Ve sed
şeritler satır numaralarını keser.
Aşağıdaki örnek bunu eylem halinde gösterir:
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'
Çıktıları:
l
k
j
i
h
g
f
e
d
c
b
a
cat -n
gibi davranırawk '{print NR" "$0}'
Perl'de:
cat <somefile> | perl -e 'while(<>) { push @a, $_; } foreach (reverse(@a)) { print; }'
perl -e 'print reverse<>'
perl -pe '$\=$_.$\}{'
)
reverse<)
hızlı: iyi! ama "gerçekten çirkin" olanı satır sayısı arttıkça oldukça yavaştır . !! ....
-n
orada gereksiz, teşekkürler.
sort
).
Yalnızca BASH çözümü
dosyayı bash dizisine (bir satır = dizinin bir elemanı) okuyun ve diziyi ters sırada yazdırın:
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=''
ve read -r
kaçışların her türlü önlemek ve yukarı vidalama gelen IFS çıkarılmasını sondaki için. Ben bash mapfile ARRAY_NAME
yerleşiminin diziler halinde okumak için daha iyi bir çözüm olduğunu düşünüyorum .
Bash, mapfile
fiximan'a yaptığı açıklamada bahsetti ve aslında daha iyi bir versiyonuyla:
# 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
}
Performansı temel olarak sed
çözümle karşılaştırılabilir ve istenen hat sayısı azaldıkça hızlanıyor.
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'
burada gösterildiği gibi:
echo 'e
> f
> a
> c
> ' | nl | sort -nr | sed -r 's/^ *[0-9]+\t//'
Sonuç:
c a f e
awk '{print NR" "$0}' | sort -nr