Здесь не нужно использовать сложные регулярные выражения. У вас есть два условия, поэтому используйте два теста:
if [[ $str == *[[:digit:]]* ]] &&
[[ $str == *[[:alpha:]]* ]]
then
printf '"%s" contains both letters and digits\n' "$str"
else
printf '"%s" lacks either letters or digits\n' "$str"
fi
Вы также говорите что-то о «специальных символах», но не уточняете, что это такое. Предполагая, что вы имеете в виду символы, соответствующие [[:punct:]]
, и что вы не хотите их в строке, вы можете использовать
if [[ $str == *[[:digit:]]* ]] &&
[[ $str == *[[:alpha:]]* ]] &&
[[ $str != *[[:punct:]]* ]]
then
printf '"%s" contains both letters and digits, and no specials\n' "$str"
else
printf '"%s" lacks either letters or digits, or contains specials\n' "$str"
fi
[[:punct:]]
будет соответствовать любому из символов в строке
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
попробуй:
printf '%s\n' "${IPS[@]}" |sort |uniq -c |sort -rn |sed 's/^ *//'
3 1.1.1.1
2 5.5.5.5
1 3.3.3.3
1 2.2.2.2
связанные:
Вы можете использовать ассоциативный массив для хранения различных IPS в виде ключей, которые будут увеличиваться при повторении массива IPS.
#!/bin/bash
IPS=("1.1.1.1" "5.5.5.5" "3.3.3.3" "1.1.1.1" "2.2.2.2" "5.5.5.5" "1.1.1.1")
declare -A arr
for ip in ${IPS[@]};
do
((arr[${ip}]++))
done
for k in ${!arr[@]};
do
echo "${arr[$k]} $k"
done | sort -rn