我有一个混合单词列表作为输入:
azert12345
a1z2e3r4t5
a1z2e3r455
我尝试执行的命令行:
cat file.txt | grep -E "[[:digit:]]{5}" --color
我想完成什么:
仅打印这些单词:“azert12345”和“a1z2e3r4t5”,使用grep
我之前说过的模式。就像是grep -E "[[:digit:]]{5}"
。
grep -E "[[:alpha:]]{5}[[:digit:]]{5}"
使用最大位数为 5、最大字母字符数为 5 来打印像“azert12345”这样的单词很容易,但问题是:我该如何打印像 a1z2e3r4t5 这样的混合单词?
“a1z2e3r4t5”只是一个例子,我应该处理的数据量要大得多
这个问题让我抓狂了三天,而且这不是作业。我将再次开始学习更多有关 linux 命令的知识。我需要一些帮助。
答案1
恕我直言,这在 awk 或 perl 中会更简单,原因如下:grep 与逻辑运算符(特别是 grep 中没有自然AND
运算符)。例如
awk 'gsub(/[a-z]/,"&") == 5 && gsub(/[0-9]/,"&") == 5' file
或者
perl -ne 'print if tr/[a-z]// == 5 && tr/[0-9]// == 5' file
将打印恰好包含每个字符集 5 个的行。
如果你坚持使用 grep,那么这样的事情可能会起作用:
grep -xE '([^a-z]*[a-z][^a-z]*){5}' file | grep -xE '([^0-9]*[0-9][^0-9]*){5}'
答案2
不使用正确的工具,看,但至少作为替代方案:
while read i; do
foo=$(echo -n $i | sed 's/[a-z]//g' | wc -c) && bar=$(echo -n $i | sed 's/[0-9]//g' | wc -c)
[[ $foo -eq 5 && $bar -eq 5 ]] && echo "$i has five digits and five alphas"
done < file
删除字母,剩下的是数字并计算它们。为了彻底,删除数字,剩下的就是字母,数一下。将每个结果保存在变量中:
foo=$(echo -n $i | sed 's/[a-z]//g' | wc -c) && bar=$(echo -n $i | sed 's/[0-9]//g' | wc -c)
如果变量的长度为 5 个字符,则字符串为五个数字和五个字母:
[[ $foo -eq 5 && $bar -eq 5 ]] && echo "$i has five digits and five alphas"
输出:
azert12345 has five digits and five alphas
a1z2e3r4t5 has five digits and five alphas
这个逻辑有问题吗?