Hiç kimsenin bash
yalnızca while
ve kullanan bariz çözümden bahsetmediğine şaşırdım read
.
while read -n1 character; do
echo "$character"
done < <(echo -n "$words")
echo -n
Sonunda gereksiz yeni satırı önlemek için kullanımına dikkat edin. printf
baş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 fold
komutu ( 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 echo
komutla her karakter karşı çalıştırmak istediğiniz Yukarıdaki örnekte kullanılan komutu. Not xargs
varsayılan olarak boşluk atar. Bu -d '\n'
davranışı devre dışı bırakmak için kullanabilirsiniz .
Uluslararasılaştırma
fold
Bazı 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 -w1
bir awk dizisiyle değiştirirdim :
awk 'BEGIN{FS=""} {for (i=1;i<=NF;i++) print $i}'
Veya grep
baş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 xargs
en 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