Emi*_*lás 10 text-processing files
我想从一个非常大的文件中提取精确的行。例如,第 8000 行会像这样得到:
command -line 8000 > output_line_8000.txt
Run Code Online (Sandbox Code Playgroud)
gni*_*urf 14
perl
和已经有答案了awk
。这是一个sed
答案:
sed -n '8000{p;q}' file
Run Code Online (Sandbox Code Playgroud)
该q
命令的优点sed
是读到第8000行就退出(不同于其他(普通创意后改了,哈哈))。perl
和awk
方法
纯粹的 Bash 可能性(bash?4):
mapfile -s 7999 -n 1 ary < file
printf '%s' "${ary[0]}"
Run Code Online (Sandbox Code Playgroud)
这将删除file
数组中的内容ary
(每个字段一行),但跳过前 7999 行 ( -s 7999
) 并且只读取一行 ( -n 1
)。
今天是星期六,我无事可做,所以我测试了其中的一些速度。事实证明sed
,gawk
和perl
方法基本上是等价的。head&tail 是最慢的,但令人惊讶的是,最快的一个数量级是纯 bash :
这是我的测试:
$ for i in {1..5000000}; do echo "This is line $i" >>file; done
Run Code Online (Sandbox Code Playgroud)
上面创建了一个 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
Run Code Online (Sandbox Code Playgroud)
您可以通过多种方式做到这一点。
使用perl
:
perl -nle 'print && exit if $. == 8000' file
Run Code Online (Sandbox Code Playgroud)
使用awk
:
awk 'FNR==8000 {print;exit}' file
Run Code Online (Sandbox Code Playgroud)
或者您可以使用tail
和head
来防止在第 8000 行之前读取整个文件:
tail -n +8000 | head -n 1
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
21055 次 |
最近记录: |