回答:
を使用sed
してエミュレートするtac
:
sed '1!G;h;$!d' ${inputfile}
sed
ワンライナーです。「36.行の逆順(Unixコマンド "tac"をエミュレート)」を参照してください。それがどのように機能するかの完全な説明については、有名なSed One-Linersで説明されています。
sort
-一時ファイルを使用する可能性があります)。
awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' file.txt
awk 'a=$0RS a{}END{printf a}'
but your first
perl reverse <> `それは(私にとって)ページ上で最高/最速の回答で、このawk
回答の10倍の速さです(すべてのawk anseresは時間的にほぼ同じです)
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
予想通り。
ただし、行はメモリに格納され、関数のインスタンスが再帰的に呼び出されるたびに1行保存されることに注意してください。大きなファイルには注意してください。
あなたはそれをパイプすることができます:
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配列に読み込み(1行=配列の1要素)、逆の順序で配列を出力します。
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
ソリューションに匹敵し、要求された行の数が減少するにつれて高速になります。