有没有一种“规范”的方法?我一直在使用head-n|tail-1来完成这个任务,但我一直在想是否有一个Bash工具专门从文件中提取一行(或一系列行)。
我所说的“规范”是指一个主要功能就是这样做的程序。
有没有一种“规范”的方法?我一直在使用head-n|tail-1来完成这个任务,但我一直在想是否有一个Bash工具专门从文件中提取一行(或一系列行)。
我所说的“规范”是指一个主要功能就是这样做的程序。
当前回答
作为CaffeineConnisseur非常有用的基准测试答案的后续。。。我很好奇“mapfile”方法与其他方法相比的速度有多快(因为没有测试),所以我自己尝试了一个快速而肮脏的速度比较,因为我手边有bash 4。在我做这项测试时,我在顶部答案的一条评论中提到了“tail|head”方法(而不是head|tail),因为人们都在称赞它。我没有使用的测试文件的大小;我能在短时间内找到的最好的文件是一个14M的谱系文件(用空格分隔的长行,略低于12000行)。
短版本:mapfile看起来比cut方法快,但比其他任何方法都慢,所以我称它为无用的。tail|head,OTOH,看起来可能是最快的,尽管与sed相比,这种大小的文件差异并不大。
$ time head -11000 [filename] | tail -1
[output redacted]
real 0m0.117s
$ time cut -f11000 -d$'\n' [filename]
[output redacted]
real 0m1.081s
$ time awk 'NR == 11000 {print; exit}' [filename]
[output redacted]
real 0m0.058s
$ time perl -wnl -e '$.== 11000 && print && exit;' [filename]
[output redacted]
real 0m0.085s
$ time sed "11000q;d" [filename]
[output redacted]
real 0m0.031s
$ time (mapfile -s 11000 -n 1 ary < [filename]; echo ${ary[0]})
[output redacted]
real 0m0.309s
$ time tail -n+11000 [filename] | head -n1
[output redacted]
real 0m0.028s
希望这有帮助!
其他回答
要使用sed和变量作为行号打印第n行,请执行以下操作:
a=4
sed -e $a'q:d' file
这里的“-e”标志用于将脚本添加到要执行的命令中。
使用其他人提到的内容,我希望这是我的bash shell中一个快速而出色的函数。
创建文件:~/.functions
添加内容:
getline(){行=$1sed$line'q;2美元}
然后将其添加到~/.bash_profile中:
source~/.函数
现在,当您打开一个新的bash窗口时,您可以这样调用函数:
获取行441 myfile.txt
作为CaffeineConnisseur非常有用的基准测试答案的后续。。。我很好奇“mapfile”方法与其他方法相比的速度有多快(因为没有测试),所以我自己尝试了一个快速而肮脏的速度比较,因为我手边有bash 4。在我做这项测试时,我在顶部答案的一条评论中提到了“tail|head”方法(而不是head|tail),因为人们都在称赞它。我没有使用的测试文件的大小;我能在短时间内找到的最好的文件是一个14M的谱系文件(用空格分隔的长行,略低于12000行)。
短版本:mapfile看起来比cut方法快,但比其他任何方法都慢,所以我称它为无用的。tail|head,OTOH,看起来可能是最快的,尽管与sed相比,这种大小的文件差异并不大。
$ time head -11000 [filename] | tail -1
[output redacted]
real 0m0.117s
$ time cut -f11000 -d$'\n' [filename]
[output redacted]
real 0m1.081s
$ time awk 'NR == 11000 {print; exit}' [filename]
[output redacted]
real 0m0.058s
$ time perl -wnl -e '$.== 11000 && print && exit;' [filename]
[output redacted]
real 0m0.085s
$ time sed "11000q;d" [filename]
[output redacted]
real 0m0.031s
$ time (mapfile -s 11000 -n 1 ary < [filename]; echo ${ary[0]})
[output redacted]
real 0m0.309s
$ time tail -n+11000 [filename] | head -n1
[output redacted]
real 0m0.028s
希望这有帮助!
这不是一个bash解决方案,但我发现顶级选择不能满足我的需求,例如,
sed 'NUMq;d' file
速度足够快,但挂了几个小时,没有告诉任何进展。我建议编译这个cpp程序并使用它来查找所需的行。您可以使用g++main.cpp编译它,其中main.cpp是包含以下内容的文件。我得到了一个,并执行了它/a.输出
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main() {
string filename;
cout << "Enter filename ";
cin >> filename;
int needed_row_number;
cout << "Enter row number ";
cin >> needed_row_number;
int progress_line_count;
cout << "Enter at which every number of rows to monitor progress ";
cin >> progress_line_count;
char ch;
int row_counter = 1;
fstream fin(filename, fstream::in);
while (fin >> noskipws >> ch) {
int ch_int = (int) ch;
if (row_counter == needed_row_number) {
cout << ch;
}
if (ch_int == 10) {
if (row_counter == needed_row_number) {
return 0;
}
row_counter++;
if (row_counter % progress_line_count == 0) {
cout << "Progress: line " << row_counter << endl;
}
}
}
return 0;
}
对于一个巨大的文件来说,头部和尾部的管道会很慢。我建议您这样做:
sed 'NUMq;d' file
其中NUM是要打印的行数;例如,sed’10q;d'文件以打印文件的第10行。
说明:
当行号为NUM时,NUMq将立即退出。
d将删除该行而不是打印该行;这在最后一行被禁止,因为q会导致退出时跳过脚本的其余部分。
如果变量中有NUM,则需要使用双引号而不是单引号:
sed "${NUM}q;d" file