[英]Regex for first part of a string to match repeated (consecutive or non-consecutive) character
[英]How to count consecutive (repeated) character in string in bash?
我想知道是否有一個簡單的 bash 或 AWK oneliner 來獲取每次重復的重復字符數。
例如考慮這個字符串:
AATGATGGAANNNNNGATAGAACGATNNNNNNNNGATAATGANNNNNNNTAGACTGA
是否有可能在第一次重復中獲得 Ns 的數量,在第二次重復中獲得 Ns 的數量,等等?
謝謝!
預期結果,每次重復的長度換行。
您可以使用awk
在每個不是N
字符上拆分字段並打印每個字段及其長度:
s='AATGATGGAANNNNNGATAGAACGATNNNNNNNNGATAATGANNNNNNNTAGACTGA'
awk -F '[^N]+' '{for (i=1; i<=NF; i++) if ($i != "") print $i, length($i)}' <<< "$s"
NNNNN 5
NNNNNNNN 8
NNNNNNN 7
另一種選擇是使用grep + awk
:
grep -Eo 'N+' <<< "$s" | awk '{print $1, length($1)}'
這是純 BASH 解決方案:
shopt -s extglob
while read -r line; do
[[ -n $line ]] && echo "$line ${#line}"
done <<< "${s//+([!N])/$'\n'}"
NNNNN 5
NNNNNNNN 8
NNNNNNN 7
BASH解決方案詳情:
non-N
字符,並用+([!N])/$'\\n'}"
換行符替換它們while
循環,我們遍歷每個N
字符的子串一個簡單的解決方案:
echo "$string" | grep -oE "N+" | awk '{ print $0, length}'
NNNNN 5
NNNNNNNN 8
NNNNNNN 7
編輯:
根據@Ed-Morton 的建議:將 -P 更改為 -E。
grep 的手冊頁說 -P 是“高度實驗性”的功能。
我們不需要 PCRE 來使用 +,只要 ERE 就足夠了。
使用用於多字符 RS 的 GNU awk:
$ awk -v RS='N+' 'RT{print length(RT)}' file
5
8
7
$ awk -v RS='N+' 'RT{print RT, length(RT)}' file
NNNNN 5
NNNNNNNN 8
NNNNNNN 7
這是一個 Perl 單行代碼:
perl -ne 'while (m/(.)(\1*)/g) { printf "%5i %s\n", length($2)+1, $1 }' <<<AATGATGGAANNNNNGATAGAACGATNNNNNNNNGATAATGANNNNNNNTAGACTGA
2 A
1 T
1 G
1 A
1 T
2 G
2 A
5 N
1 G
1 A
1 T
1 A
1 G
2 A
1 C
1 G
1 A
1 T
8 N
1 G
1 A
1 T
2 A
1 T
1 G
1 A
7 N
1 T
1 A
1 G
1 A
1 C
1 T
1 G
1 A
m/(.)(\\1*)/
連續匹配盡可能多的相同字符, /g
導致匹配在下一次迭代中再次出現,只要字符串仍然包含一些我們還沒有的東西匹配。 因此,我們以相同字符的塊循環遍歷字符串,並且在每次迭代時,打印第一個字符以及整個匹配字符串的長度。
第一對括號在(剩余的不匹配)行的開頭捕獲一個字符, \\1
表示重復該字符。 *
量詞盡可能多地與此匹配。
如果您只對 N:s 感興趣,您可以將第一個括號更改為(N)
,或者您可以添加一個條件,如printf("%7i %s\\n", length($2), $1) if ($1 == "N")
。 同樣,如果您只想要重復(多次出現)的命中,您可以說\\1+
而不是\\1*
或添加一個條件,如... if length($2) >= 1
。
當您要求 sed 解決方案時,如果您的重復字符鏈不超過 9 個字符並且您的字符串不包含任何分號,則可以使用此解決方案:
sed 's/$/;NNNNNNNNN0123456789/;:a;s/\\(N\\+\\)\\([^;]*;\\1.\\{9\\}\\)\\(.\\)\\(.*\\)/\\2\\3\\4\\n\\3/;ta;s/[^\\n]*\\n//'
試試這兩個:
第一個
sed 's/[^N]/ /g' file | awk '{for(i=1;i<=NF;i++){print $i":"length($i)}}'
第二個
cat file | tr -c 'N' ' ' | awk '{for(i=1;i<=NF;i++){print $i":"length($i)}}'
簡短的 GNU awk方法:
str='AATGATGGAANNNNNGATAGAACGATNNNNNNNNGATAATGANNNNNNNTAGACTGA'
awk -v FPAT='N+' '{for(i=1;i<=NF;i++) print $i,length($i)}' <<< $str
輸出:
NNNNN 5
NNNNNNNN 8
NNNNNNN 7
您可以借助正則表達式方法。
這是我從以下鏈接獲得的解決方案代碼
needle=","
var="text,text,text,text"
number_of_occurrences=$(grep -o "$needle" <<< "$var" | wc -l)
如您所見,在 WC(字數)的幫助下,我們可以很容易地獲得“$needle”的出現次數。
您可以循環它以滿足您的需求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.