非常に大きなファイルから正確な行を抽出したい。たとえば、8000行目は次のようになります。
command -line 8000 > output_line_8000.txt
Perl
とawk
にはすでに回答があります。これがsed
の回答です。
sed -n '8000{p;q}' file
q
コマンドの利点は、8000行目が読み取られるとすぐにsed
が終了することです(他の (それは共通の創造性の後に変更されました、笑))。Perl
およびawk
メソッドとは異なり
純粋なBashの可能性(bash≥4):
mapfile -s 7999 -n 1 ary < file
printf '%s' "${ary[0]}"
これにより、file
の内容が配列ary
(フィールドごとに1行)に含まれますが、最初の7999行はスキップされます(-s 7999
)と1行だけ読み取ります(-n 1
)。
土曜日だし、他に何もすることがなかったので、速度をテストした。 sed
、gawk
、Perl
のアプローチは基本的に同等であることがわかります。ヘッド&テールの方が最も遅いですが、驚いたことに、最速桁違いは純粋なbashの方です。
これが私のテストです:
$ for i in {1..5000000}; do echo "This is line $i" >>file; done
上記は、1億を占める5,000万行のファイルを作成します。
$ for cmd in "sed -n '8000{p;q}' file" \
"Perl -ne 'print && exit if $. == 8000' file" \
"awk 'FNR==8000 {print;exit}' file"
"head -n 8000 file | tail -n 1" \
"mapfile -s 7999 -n 1 ary < file; printf '%s' \"${ary[0]}\"" \
"tail -n 8001 file | head -n 1"; do
echo "$cmd"; for i in {1..100}; do
(time eval "$cmd") 2>&1 | grep -oP 'real.*?m\K[\d\.]+'; done |
awk '{k+=$1}END{print k/100}';
done
sed -n '8000{p;q}' file
0.04502
Perl -ne 'print && exit if $. == 8000' file
0.04698
awk 'FNR==8000 {print;exit}' file
0.04647
head -n 8000 file | tail -n 1
0.06842
mapfile -s 7999 -n 1 ary < file; printf '%s' "This is line 8000
"
0.00137
tail -n 8001 file | head -n 1
0.0033
あなたはそれを多くの方法で行うことができます。
Perl
の使用:
Perl -nle 'print && exit if $. == 8000' file
awk
の使用:
awk 'FNR==8000 {print;exit}' file
または、tail
およびhead
を使用して、8000行目までファイル全体を読み取らないようにすることができます。
tail -n +8000 | head -n 1
tail
およびhead
を含む別のバージョン
head -n 8000 file | tail -n 1
sed
を使用できます:
sed -n '8000p;' filename
ファイルが大きい場合は、終了することをお勧めします。
sed -n '8000p;8001q' filename
同様に、awk
またはPerl
を使用してファイル全体の読み取りを中止することもできます。
awk 'NR==8000{print;exit}' filename
Perl -ne 'print if $.==8000; last if $.==8000' filename
これはどう?
$ cat -n filename | grep -E "[ \t]+8000"
$ cat -n /etc/abrt/plugins/CCpp.conf | grep -E "^[ \t]+16"
16 #DebuginfoLocation = /var/cache/abrt-di