Answers:
使用sed
效仿tac
:
sed '1!G;h;$!d' ${inputfile}
sed
的单线飞机。请参见“ 36.行的逆序(模拟“ tac” Unix命令”)。在著名桑达单行解释了它是如何工作的完整说明。
sort
-可能会使用一个临时文件)。
awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' file.txt
通过awk一班轮
awk 'a=$0RS a{}END{printf a}'
but your first
perl reverse <>`它是页面上最好/最快的答案(对我来说),比该awk
答案快10倍(所有awk答案在时间上都
awk '{a[NR]=$0} END {while (NR) print a[NR--]}'
当您要求在bash中进行操作时,这是一个不使用awk,sed或perl的解决方案,而只是使用bash函数:
reverse ()
{
local line
if IFS= read -r line
then
reverse
printf '%s\n' "$line"
fi
}
输出
echo 'a
b
c
d
' | reverse
是
d
c
b
a
如预期的那样。
但是要注意,行存储在内存中,在每个递归调用的函数实例中只有一行。大文件时要格外小心。
您可以通过以下方式传递它:
awk '{print NR" "$0}' | sort -k1 -n -r | sed 's/^[^ ]* //g'
awk
每行的前缀是行号,后跟一个空格。通过以sort
相反的顺序(数字样式)在第一个字段(行号)上排序来反转行的顺序。然后sed
删除行号。
下面的示例演示了此操作:
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'
它输出:
l
k
j
i
h
g
f
e
d
c
b
a
cat -n
行为很像awk '{print NR" "$0}'
在perl中:
cat <somefile> | perl -e 'while(<>) { push @a, $_; } foreach (reverse(@a)) { print; }'
perl -e 'print reverse<>'
perl -pe '$\=$_.$\}{'
)
reverse<)
很快:很好!但是随着行数的增加,“真的很丑”的速度非常慢。!! ....
-n
那里多余,谢谢。
sort
)。
仅BASH解决方案
将文件读入bash数组(一行=数组的一个元素)并以相反的顺序打印出数组:
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=''
和read -r
防止各种逃脱和尾随IFS的拆卸将其拧紧。我认为mapfile ARRAY_NAME
内置的bash 是读取数组的更好解决方案。
Bash,mapfile
在Fiximan的评论中提到过,实际上是一个可能更好的版本:
# 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
}
其性能基本上可与 sed
解决方案,并且随着请求的行数减少而变得更快。
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'