如何从文件中获取特定行?

如何从文件中获取特定行?

我想从一个非常大的文件中提取精确的行。例如,第 8000 行将如下所示:

command -line 8000 > output_line_8000.txt

答案1

perl和已经有答案了awk。这是一个sed答案:

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

该命令的优点qsed读到第8000行就退出(不像其他perlandawk方法(经过共同创意改的,哈哈))。

纯粹的 Bash 可能性(bash≥4):

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

file这将读取数组中的内容ary(每个字段一行),但跳过前 7999 行 ( -s 7999) 并且只读取一行 ( -n 1)。

答案2

今天是星期六,我没什么更好的事情可做,所以我测试了其中一些的速度。事实证明,sedgawkperl方法基本上是等效的。头部和尾部是最慢的,但令人惊讶的是,最快一个数量级是纯 bash 的:

这是我的测试:

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

以上创建了一个5000万行的文件,占用100M。

$ 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

或者您可以使用tailhead来阻止读取整个文件直到第 8000 行:

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

相关内容