ファイルから特定の行を取得する方法は? [コピー]

ファイルから特定の行を取得する方法は? [コピー]

非常に大きなファイルから正確な行を抽出したいと思います。たとえば、8000行は次のようになります。

command -line 8000 > output_line_8000.txt

答え1

perlそしてすでに答えを持っていますawk。答えは次のとおりですsed

sed -n '8000{p;q}' file

このコマンドの利点は、8000行を読んだ後に終了するqことです(他の方法とは異なり(共同創造性を介して変更された、ハハ))。sedperlawk

純粋なBashの可能性(bash≥4):

mapfile -s 7999 -n 1 ary < file
printf '%s' "${ary[0]}"

fileその後、配列の内容ary(フィールドごとに1行)を読み取りますが、最初の7999行(-s 7999)をスキップして1行(-n 1)のみを読み込みます。

答え2

土曜日ですが、これ以上やることがないので、いくつかの速度をテストしてみました。sedgawkおよびメソッドは基本的に同じであることがわかりましたperl。頭と尾が最も遅いが、驚くべきことに最も速い。一次純粋なbashです。

私のテストは次のとおりです。

$ for i in {1..5000000}; do echo "This is line $i" >>file; done

上記は、1億ラインを占める5000万ラインのファイルを生成します。

$ 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

答え3

さまざまな方法でこれを実行できます。

使用perl:

perl -nle 'print && exit if $. == 8000' file

使用awk:

awk 'FNR==8000 {print;exit}' file

または、tail次のようにして、head8000行までファイル全体を読み取らないようにすることもできます。

tail -n +8000 | head -n 1

答え4

あなたが使用できる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

関連情報