在bash中获取列表的一部分

时间:2018-09-22 16:48:22

标签: bash list shell

我需要分成3个列表,类似的列表超过3000行。我需要以这样的方式进行划分:我可以指定诸如此类的东西:

  1. chunk->从以“ a”开头的单词直到以“ e”开头的单词(包括所有以字母“ e”开头的单词)。
  2. chunk->从以“ f”开头的单词,直到以“ mj”开头的单词(包括所有以“ mj”开头的单词)。
  3. chunk->从以“ mk”开头的单词,直到以“ z”开头的单词。

示例输入:

about
block
echo
far
maps
mjalgo
mjprou
mksomething
november
opshacom
oscar
softball
zorro

任何想法如何实现这一目标?我不需要一个命令来完成所有操作,我只需要知道如何为每个所需的块编写1个命令即可。

谢谢!

3 个答案:

答案 0 :(得分:2)

使用范围类型的正则表达式,例如/^c/ -- /^dd/,您可以在已排序的文件上使用sed:

$ sed -nE '/^c/,/^dd/p' file.txt
caccount@example.com
daccount@example.com
ddaccount@domain.com

或perl:

$ perl -ne 'print if /^c/ .. /^dd/' file.txt
caccount@example.com
daccount@example.com
ddaccount@domain.com

或者awk:

$ awk '/^c/,/^dd/' file.txt
caccount@example.com
daccount@example.com
ddaccount@domain.com

基于新帖子:

如果您希望按不同的正则表达式分组,awk是最好的选择(或多次运行sed grep等)

示例:

$ cat file.txt
about
block
echo
far
maps
mjalgo
mjprou
mksomething
november
opshacom
oscar
softball
zorro

您可以这样做:

$ awk '/^[a-e]/               {print $0>"f1.txt"; next}
     /^[f-k]/ || /^m[a-j]/    {print $0>"f2.txt"; next}
     /^m[k-z]/ || /^[n-z]/    {print $0>"f3.txt"; next}
     ' file.txt

然后将3个存储桶放在3个不同的文件中:

for fn in f{1..3}.txt; do
    sort "$fn"
    echo "==="
done   

打印:

about
block
blood
echo
===
maps
mjalgo
mjprou
===
mksomething
november
opshacom
oscar
softball
zorro
===

如果对输入进行了排序,则不需要对每个文件进行排序。如果您拥有gawk与POSIX awk,则可以在内部对行进行排序。

答案 1 :(得分:1)

$ awk '$0>="c" && $0<"dd"' file
caccount@example.com
daccount@example.com

答案 2 :(得分:0)

您可以尝试使用csplit

csplit infile /^f/ /^mk/