Hiç kimsenin bashyalnızca whileve kullanan bariz çözümden bahsetmediğine şaşırdım read.
while read -n1 character; do
echo "$character"
done < <(echo -n "$words")
echo -nSonunda gereksiz yeni satırı önlemek için kullanımına dikkat edin. printfbaşka bir iyi seçenektir ve özel ihtiyaçlarınız için daha uygun olabilir. Boşluğu yok saymak istiyorsanız, "$words"ile değiştirin "${words// /}".
Başka bir seçenek de fold. Ancak bunun asla bir for döngüsüne beslenmemesi gerektiğini lütfen unutmayın. Bunun yerine aşağıdaki gibi bir while döngüsü kullanın:
while read char; do
echo "$char"
done < <(fold -w1 <<<"$words")
Harici foldkomutu ( coreutils paketinin) kullanmanın birincil faydası kısalık olacaktır. Çıktısını aşağıdaki gibi xargs( findutils paketinin parçası) gibi başka bir komuta besleyebilirsiniz :
fold -w1 <<<"$words" | xargs -I% -- echo %
Sen değiştirmek isteyeceksiniz echokomutla her karakter karşı çalıştırmak istediğiniz Yukarıdaki örnekte kullanılan komutu. Not xargsvarsayılan olarak boşluk atar. Bu -d '\n'davranışı devre dışı bırakmak için kullanabilirsiniz .
Uluslararasılaştırma
foldBazı Asya karakterleriyle test ettim ve Unicode desteğine sahip olmadığını fark ettim. Yani ASCII ihtiyaçları için uygun olsa da, herkes için işe yaramayacak. Bu durumda bazı alternatifler var.
Muhtemelen fold -w1bir awk dizisiyle değiştirirdim :
awk 'BEGIN{FS=""} {for (i=1;i<=NF;i++) print $i}'
Veya grepbaşka bir cevapta bahsedilen komut:
grep -o .
Verim
Bilginize, yukarıda belirtilen 3 seçeneği karşılaştırdım. İlk ikisi hızlıydı, neredeyse bağlıydı ve katlama döngüsü while döngüsünden biraz daha hızlıydı. Şaşırtıcı olmayan bir şekilde xargsen yavaştı ... 75 kat daha yavaş.
İşte (kısaltılmış) test kodu:
words=$(python -c 'from string import ascii_letters as l; print(l * 100)')
testrunner(){
for test in test_while_loop test_fold_loop test_fold_xargs test_awk_loop test_grep_loop; do
echo "$test"
(time for (( i=1; i<$((${1:-100} + 1)); i++ )); do "$test"; done >/dev/null) 2>&1 | sed '/^$/d'
echo
done
}
testrunner 100
Sonuçlar burada:
test_while_loop
real 0m5.821s
user 0m5.322s
sys 0m0.526s
test_fold_loop
real 0m6.051s
user 0m5.260s
sys 0m0.822s
test_fold_xargs
real 7m13.444s
user 0m24.531s
sys 6m44.704s
test_awk_loop
real 0m6.507s
user 0m5.858s
sys 0m0.788s
test_grep_loop
real 0m6.179s
user 0m5.409s
sys 0m0.921s