我编写了使用grep
搜索和计算字符串出现次数的代码。但是,它没有考虑滑动窗口。
尝试:
grep -E -o "(A|B){2}" datafile | sort | uniq -c
数据文件:
AABBABAABBBA
输出:
2 AA
1 AB
1 BA
2 BB
预期产出:
2 AA
3 BA
3 AB
2 BB
答案 0 :(得分:1)
怎么样,
for i in {"AA","AB","BA","BB"}; do echo "AABBABAABBBA" | grep -o $i; done | sort | uniq -c
我认为这并不简单。
无论如何......它会让你想要的东西回归!
答案 1 :(得分:1)
您可以使用:
awk 'BEGIN {FS=""}{for(i=2; i<=NF; i++)
print $(i-1) $i}' datafile | grep -Eo "[AB]{2}" | sort | uniq -c
2 AA
3 AB
3 BA
3 BB
答案 2 :(得分:1)
使用perl:
$ echo AABBABAABBBA | perl -nE 'say for /(?<=([AB]{2}))/g' | sort | uniq -c
2 AA
3 AB
3 BA
3 BB
注意:上述解决方案的灵感来自this answer ...
答案 3 :(得分:1)
如果使用bash
4.0或更高版本,您可以使用关联数组来跟踪每个唯一的两个字符集及其计数:
declare -A list
while read -r line; do
for ((i=0;i<=$((${#line}-2));i++)); do
ref="${line:$i:2}"
if [[ ${!list[@]} != *"$ref"* ]]; then
list["$ref"]=1
else
((list["$ref"]++))
fi
done
done < file
for index in "${!list[@]}"; do
echo "${list[$index]} $index"
done
输出:
3 AB
2 AA
3 BB
3 BA
答案 4 :(得分:0)
为什么您希望输出与您显示的一样?分解:
$ echo AABBABAABBBA | grep -E -o "(A|B){2}"
AA
BB
AB
AA
BB
BA
现在sort
:
$ echo AABBABAABBBA | grep -E -o "(A|B){2}" | sort
AA
AA
AB
BA
BB
BB
注意: AB
在排序后BA
之前发生。现在找uniq
:
$ echo AABBABAABBBA | grep -E -o "(A|B){2}" | sort | uniq -c
2 AA
1 AB
1 BA
2 BB
在AB
之前 sort
始终BA
(除非相反)。如果您反转sort
,则会反转整个答案。
要创建滑动窗口,您可以沿着字符串向下走:
str=AABBABAABBBA; for ((i=0; i<$((${#str}-1)); i++)); do \
printf "%s\n" "${str:$i:2}"; done | sort | uniq -c
<强>输出:强>
2 AA
3 AB
3 BA
3 BB
或者按照jaypal的建议:
echo "AABBABAABBBA" | awk -v FS= \
'{for(i=1;i<NF;i++)a[$i,$(i+1)]++}END{for(x in a) print a[x],x}'
2 AA
3 AB
3 BA
3 BB
答案 5 :(得分:0)
Bash解决方案:
#!/bin/bash
while read str
do
len=$(echo "${#str}")
i=0
#Convert the string in to array
ar=($(while [[ "$len" -gt "$i" ]];do echo "${str:i:1}";let "i = $i + 1";done))
k=0
#iterate through array and print the string for piping it into grep
for ((j=0;j<${#ar[@]};j++))
do
k=$((k = j+1))
[ "$k" -lt "$len" ] && echo "${ar[j]}${ar[k]}"
done
done < datafile > datafile1
grep -hoP '\b\w+\b' < datafile1 | sort | uniq -c
答案 6 :(得分:0)
这是一种perl方式:
$ echo AABBABAABBBA |
perl -F"" -alne 'for($i=0;$i<$#F;$i++){$k{$F[$i].$F[$i+1]}++}
print "$_ : $k{$_}" for keys(%k); '
AA : 2
BB : 3
AB : 3
BA : 3
-F
将字段分隔符设置为空字符串,-an
将每个输入行的值-F
分割为@F
数组。结果是一个数组,其中每个元素都是输入的单个字母。然后我们创建一个哈希,其密钥每组包含2个连续的字母($F[$i] . $F[$i+1]
),然后在每次找到两个字母组合时递增相应的值。最后,键和它们的值以for
循环打印。
答案 7 :(得分:0)
Bash解决方案
str="AABBABAABBBA"
for i in `seq 1 ${#str}`; do
echo $str | cut -c${i}-
done | grep -Eo '^(A|B){2}' | sort | uniq -c
for循环构建原始字符串的所有较短尾部子串
AABBABAABBBA
ABBABAABBBA
BBABAABBBA
BABAABBBA
ABAABBBA
BAABBBA
AABBBA
ABBBA
BBBA
BBA
BA
A