首页 > 解决方案 > 在 bash 中获取列表的一部分

问题描述

我需要分成 3 个类似的列表,其中包含超过 3000 行。我需要以可以指定以下内容的方式进行划分:

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

示例输入:

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

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

谢谢!

标签: bashlistshell

解决方案


使用范围类型正则表达式,就像/^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
===

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


推荐阅读