![文字が連続して表示される頻度を確認する[閉じる]](https://linux33.com/image/90040/%E6%96%87%E5%AD%97%E3%81%8C%E9%80%A3%E7%B6%9A%E3%81%97%E3%81%A6%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%82%8B%E9%A0%BB%E5%BA%A6%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B%5B%E9%96%89%E3%81%98%E3%82%8B%5D.png)
(Bashでは)文字の連続的な発生を確認する方法が必要ですが、文字を2番目の変数として扱う前に発生回数を制限して、より大きなセットが最初に表示されるようにする必要があります。たとえば、バイナリ文字があり、次のことができるスクリプトが必要であるとします。
01111100
次のように報告されています
03200
または
01001111
〜のように
010031
または
01011001
〜のように
0102001
お願いしますいいえ、bashシェルに入る唯一の方法でなければ。
答え1
Perlが気に入らなければできます。
1シーケンスの単一の0または1〜3インスタンスに一致します。
ゼロを自分にマッピングし、シーケンスを長さにマップします。
例えば
perl -lne '@runs = $_ =~ /(0|1{1,3})/g; print map { $_==0 ? $_ : length $_ } @runs'
提供された文字列を使用してテストします。
cat << EOF | \
perl -lne '@runs = $_ =~ /(0|1{1,3})/g; print map { $_==0 ? $_ : length $_ } @runs'
01111100
01001111
01011001
EOF
出力
03200
010031
0102001
Perlがオプションでない場合は、grepやbash配列の使用などの他の正規表現ツールを使用して同じことを実行できます。
mapfile -t runs < <(echo '01111100' | grep -Eo '0|1{1,3}')
それから
for r in "${runs[@]}"; do ((r == 0)) && printf '0' || printf '%d' "${#r}"; done; printf '\n'
03200