质数的Bash解析列表。

时间:2016-10-05 08:15:50

标签: bash parsing

我想解析一下我从文件中获取的六元组列表,然后解析它们的唯一六元组并对它们进行排序。

列表如下所示:

   1 0xb6e38000
   8 0xb6f66000
   5 0xb6f69000
   1 0xb6f6c000
   3 0xb6fd4000
   1 0xb6ff7000
   2 0xb6ff8000
   4 0xb6ffa000
   1 0xb6ffb000

现在我想要做的是,进一步完善它,以便我只得到前面带有素数的六边形,如下所示:

   1 0xb6e38000
   5 0xb6f69000
   1 0xb6f6c000
   3 0xb6fd4000
   1 0xb6ff7000
   1 0xb6ffb000 

我一直在使用的命令是:

sort | uniq -c | grep  " 1 0x" 

但是此命令仅列出文件中仅出现一次的命令。 任何人都可以帮助我“排除”这个吗?

1 个答案:

答案 0 :(得分:2)

素数的原始答案

正如问题评论中所述,1不是prime,但在所需输出的描述中,您列出了以1开头的行。但是,如果您确实要在第一列中过滤掉带有素数的行,那么以下脚本将有所帮助:

#!/bin/bash -

[ $# -gt 0 ] && source_file="$1"

: ${source_file:=/tmp/source-file}

function is_prime {
  declare -i n="$1"

  if [ $n -le 1 ]; then
    return 1
  elif [ $n -le 3 ]; then
    return 0
  elif [[ $(( $n % 2 )) == 0 || $(( $n % 3 )) == 0 ]]; then
    return 1
  fi

  i=5
  while [[ $(( $i * $i )) -le $n ]]; do
    if [[  $(( $n % $i )) == 0 || $(( $n % ($i + 2) ))  == 0 ]]; then
      return 1
    fi
    (( i += 6 ))
  done
  return 0
}

while read -a line; do
  # We accept only two or more columns
  [ ${#line[@]} -ge 2 ] || continue;
  if is_prime ${line[0]}; then
    echo $line
  else
    echo >&2 "skipping ${line[*]} as ${line[0]} is not prime"
  fi
done < "$source_file"

在这个脚本中,如果第一个参数(is_prime)是素数,我们定义$1函数返回零(成功状态)。非零表示非素数。该算法是翻译成Bash的this伪代码的版本。

然后我们逐行阅读$source_file while循环,我们将列放入line数组:read -a line。然后我们检查is_prime ${line[0]}命令是否以成功代码(零)退出,如果是,则输出该行。否则,我们会将消息打印为标准错误(echo >&2)。

脚本接受源文件路径的可选参数。如果缺少第一个参数,它会将$source_file分配给/tmp/source-file

脚本用法

  1. 将上述代码保存在script.sh文件中。
  2. 致电bash script.sh /path/to/source-file >filtered 2>errors
  3. 检查filterederrors个文件的内容。第一个将包含从源文件中过滤掉的行。
  4. 输出文件如下所示:

    过滤

    5 0xb6f69000
    3 0xb6fd4000
    2 0xb6ff8000
    

    错误

    skipping 1 0xb6e38000 as 1 is not prime
    skipping 8 0xb6f66000 as 8 is not prime
    skipping 1 0xb6f6c000 as 1 is not prime
    skipping 1 0xb6ff7000 as 1 is not prime
    skipping 4 0xb6ffa000 as 4 is not prime
    skipping 1 0xb6ffb000 as 1 is not prime
    

    奇数的更新

      

    我从一开始就提到这个,我需要奇数行   出现,而不是素。我的错。 - 生物

    如果数字是奇数的,if [[ $(( $n % 2 )) != 0 ]]这样的表达式很容易检测到。该表达式检查2的余数是否不等于零,即应用modulo operation。如果余数为零,那么数字是偶数,否则当然是奇数。

    完整的脚本:

    #!/bin/bash -
    
    [ $# -gt 0 ] && source_file="$1"
    
    : ${source_file:=/tmp/source-file}
    
    
    while read -a line; do
      # We accept only two or more columns
      [ ${#line[@]} -ge 2 ] || continue;
      declare -i n=${line[0]}
      if [[ $(( $n % 2 )) != 0 ]]; then
        echo ${line[*]}
      else
        echo >&2 "skipping ${line[*]} as ${line[0]} is even"
      fi
    done < "$source_file"
    

    如上所述,您运行bash script.sh /path/to/source-file >filtered 2>errors

    示例输出:

    过滤

    1 0xb6e38000
    5 0xb6f69000
    1 0xb6f6c000
    3 0xb6fd4000
    1 0xb6ff7000
    1 0xb6ffb000
    

    错误

    skipping 8 0xb6f66000 as 8 is even
    skipping 2 0xb6ff8000 as 2 is even
    skipping 4 0xb6ffa000 as 4 is even