我想解析一下我从文件中获取的六元组列表,然后解析它们的唯一六元组并对它们进行排序。
列表如下所示:
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"
但是此命令仅列出文件中仅出现一次的命令。 任何人都可以帮助我“排除”这个吗?
答案 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
。
脚本用法
script.sh
文件中。bash script.sh /path/to/source-file >filtered 2>errors
filtered
和errors
个文件的内容。第一个将包含从源文件中过滤掉的行。输出文件如下所示:
过滤
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