我想从一个非常大的文件中提取精确的行。例如,第 8000 行将如下所示:
command -line 8000 > output_line_8000.txt
答案1
perl
和已经有答案了awk
。这是一个sed
答案:
sed -n '8000{p;q}' file
该命令的优点q
是sed
读到第8000行就退出(不像其他(经过共同创意改的,哈哈))。perl
andawk
方法
纯粹的 Bash 可能性(bash≥4):
mapfile -s 7999 -n 1 ary < file
printf '%s' "${ary[0]}"
file
这将读取数组中的内容ary
(每个字段一行),但跳过前 7999 行 ( -s 7999
) 并且只读取一行 ( -n 1
)。
答案2
今天是星期六,我没什么更好的事情可做,所以我测试了其中一些的速度。事实证明,sed
、gawk
和perl
方法基本上是等效的。头部和尾部是最慢的,但令人惊讶的是,最快一个数量级是纯 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
或者您可以使用tail
和head
来阻止读取整个文件直到第 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