Câu trả lời:
Sử dụng sed
để mô phỏng tac
:
sed '1!G;h;$!d' ${inputfile}
sed
lớp lót nổi tiếng . Xem "36. Thứ tự đảo ngược của dòng (mô phỏng lệnh" tac "Unix)." trong Nổi tiếng Sed One-Liners Giải thích cho một lời giải thích đầy đủ về cách thức hoạt động của nó.
sort
- có khả năng nó sẽ sử dụng một tệp tạm thời).
Với ed
:
ed -s infile <<IN
g/^/m0
,p
q
IN
Nếu bạn đang bật BSD
/ OSX
(và hy vọng sẽ sớm bật GNU
/ linux
vì nó sẽ là POSIX ):
tail -r infile
awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' file.txt
thông qua awk một lót
awk 'a=$0RS a{}END{printf a}'
but your first
Perl đảo ngược <> `nó là câu trả lời tốt nhất / nhanh nhất trên trang (với tôi), lúc 10 lần nhanh hơn so với này awk
câu trả lời (tất cả các anseres awk là như nhau, thời gian khôn ngoan)
awk '{a[NR]=$0} END {while (NR) print a[NR--]}'
Như bạn đã yêu cầu làm điều đó trong bash, đây là một giải pháp không sử dụng awk, sed hoặc perl, chỉ là một hàm bash:
reverse ()
{
local line
if IFS= read -r line
then
reverse
printf '%s\n' "$line"
fi
}
Đầu ra của
echo 'a
b
c
d
' | reverse
Là
d
c
b
a
Như mong đợi.
Nhưng hãy cẩn thận rằng các dòng được lưu trữ trong bộ nhớ, một dòng trong mỗi thể hiện được gọi đệ quy của hàm. Vì vậy, cẩn thận với các tập tin lớn.
Bạn có thể dẫn nó qua:
awk '{print NR" "$0}' | sort -k1 -n -r | sed 's/^[^ ]* //g'
Các awk
tiền tố mỗi dòng với số dòng theo sau là khoảng trắng. Việc sort
đảo ngược thứ tự của các dòng bằng cách sắp xếp trên trường đầu tiên (số dòng) theo thứ tự ngược lại, kiểu số. Và các sed
dải ra khỏi số dòng.
Ví dụ sau đây cho thấy điều này trong hành động:
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'
Nó xuất ra:
l
k
j
i
h
g
f
e
d
c
b
a
cat -n
hành động giống nhưawk '{print NR" "$0}'
Trong perl:
cat <somefile> | perl -e 'while(<>) { push @a, $_; } foreach (reverse(@a)) { print; }'
perl -e 'print reverse<>'
perl -pe '$\=$_.$\}{'
)
reverse<)
là nhanh: tốt! nhưng cái "thực sự xấu xí" thì cực kỳ chậm khi số dòng tăng lên. !! ....
-n
là không cần thiết ở đó, cảm ơn.
sort
).
Giải pháp chỉ BASH
đọc tệp vào mảng bash (một dòng = một phần tử của mảng) và in ra mảng theo thứ tự ngược lại:
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=''
và read -r
để ngăn chặn tất cả các loại thoát và theo dõi loại bỏ IFS khỏi làm hỏng nó. Tôi nghĩ rằng bash mapfile ARRAY_NAME
dựng sẵn là một giải pháp tốt hơn để đọc vào mảng mặc dù.
Bash, với các mapfile
ý kiến được đề cập đến fiximan, và thực sự là một phiên bản có thể tốt hơn:
# 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
}
Hiệu suất của nó về cơ bản có thể so sánh với sed
giải pháp và nhanh hơn khi số lượng dòng được yêu cầu giảm.
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'
như được hiển thị ở đây:
echo 'e
> f
> a
> c
> ' | nl | sort -nr | sed -r 's/^ *[0-9]+\t//'
Kết quả:
c a f e
awk '{print NR" "$0}' | sort -nr