我知道要从我可以执行的文件中提取行的子集:
sed -n 2208202,2218201p file >>new
bash中有没有办法根据单词提取文件的子集(保留确切的顺序)?例如,提取文件的前10k个单词,或10000到20000的单词?
答案 0 :(得分:3)
将此作为测试文件:
$ cat file
one two
three four five
six seven
eight nine
ten eleven twelve
thirteen
fourteen
使用GNU awk
(gawk
),让我们选择单词4到10:
$ awk -v RS='[[:space:]]+' '4<=NR && NR<=10{ printf "%s%s",$0,RT } END{print""}' file
four five
six seven
eight nine
ten
请注意,这会保留原始文件的空格和换行符。
-v RS='[[:space:]]+'
这会将awk的记录分隔符设置为任何空格组合。
4<=NR && NR<=10{ printf "%s%s",$0,RT }
对于记录4到10,这将打印记录,其中包含输入文件中的任何空格。 RT
不是POSIX。
END{print""}
如果最后一个单词不是一行中的最后一个单词,则会打印最终换行符。
答案 1 :(得分:1)
假设:
尝试:
awk -v from=10000 -v to=20000 -v RS='[[:space:]]+' 'NR < from {next} NR > to {exit} 1' file
- 只需省略-v from=...
即可以第一个字开头
- 此解决方案在输出上打印每个单词;相反,如果您想保留单词之间的原始空格,请参阅John1024's helpful answer。
RS='[[:space:]]+'
将输入记录分隔符(RS
)定义为任何空格运行,这有效地使每个非空白字符的运行成为自己的记录。
RS
值可使此解决方案符合非POSIX标准;同样在OS X上使用的BSD awk
仍然接近POSIX规范。因此不支持这样的RS
值。NR < from {next}
低于范围的起始索引, NR
就会跳过输入记录。
NR > to {exit}
就会完全退出。这可能是一个包含大量输入文件的重要优化。
1
,{ print }
的常用简写,在各自的行上打印,因为print
打印每个输入记录,然后是值ORS
,即输出记录分隔符,默认为\n
。
警告:第一个单词前面前面的空格报告为空字(记录)。
答案 2 :(得分:1)
awk
救援!
这也适用于其他问题
$ awk -v n=15 'sum<n && p{print p}
{p=$0; sum+=NF}
sum>=n{exit}
END{for(i=1;i<=n-sum+NF;i++) printf "%s ", $i;
print ""}' file.txt
这是第一个n字脚本。范围可以类似地实现。