Bir kelimenin harflerini, her harf ayrı bir satırda olacak şekilde nasıl bölebilirim?
Örneğin, "StackOver"
görmek istediğim gibi
S
t
a
c
k
O
v
e
r
Bash için yeniyim, bu yüzden nereden başlayacağımla ilgili hiçbir fikrim yok.
Bir kelimenin harflerini, her harf ayrı bir satırda olacak şekilde nasıl bölebilirim?
Örneğin, "StackOver"
görmek istediğim gibi
S
t
a
c
k
O
v
e
r
Bash için yeniyim, bu yüzden nereden başlayacağımla ilgili hiçbir fikrim yok.
Yanıtlar:
Kullanacağım grep
:
$ grep -o . <<<"StackOver"
S
t
a
c
k
O
v
e
r
veya sed
:
$ sed 's/./&\n/g' <<<"StackOver"
S
t
a
c
k
O
v
e
r
Ve sonunda boş alan bir sorunsa:
sed 's/\B/&\n/g' <<<"StackOver"
Bunların hepsi GNU / Linux olduğunu varsayar.
Here string
grosso modo eşdeğeri olarak adlandırılır echo foo | ...
. Bkz tldp.org/LDP/abs/html/x17837.html
.
için \B
(sözcük sınırında uymuyor).
sed
gibi bırakabilirsiniz :sed -et -e's/./\n&/g;//D'
Amaç metni dikey olarak yazdırmaksa, karakterler yerine grafik kümelerini kırmak isteyebilirsiniz. Örneğin e
, akut aksanlı bir a:
Grafeme kümeleriyle ( e
akut vurgusu ile bir grafik kümesi kümesi olur):
$ perl -CLAS -le 'for (@ARGV) {print for /\X/g}' $'Ste\u301phane'
S
t
é
p
h
a
n
e
(veya grep -Po '\X'
PCRE desteği ile oluşturulmuş GNU grep ile)
Karakterlerle (burada GNU ile grep
):
$ printf '%s\n' $'Ste\u301phane' | grep -o .
S
t
e
p
h
a
n
e
fold
karakterleri kırmaya yöneliktir, ancak GNU fold
çok baytlı karakterleri desteklemez, bunun yerine baytlara ayrılır:
$ printf '%s\n' $'Ste\u301phane' | fold -w 1
S
t
e
�
�
p
h
a
n
e
Yalnızca ASCII karakterlerden (yani karakter başına bir bayt, grafik kümesi başına bir karakter) oluşan StackOver üzerinde , üçü de aynı sonucu verir.
grep -Po
biri beklendiği gibi grep -P
yapmaz (olduğu gibi ).
grep -Po .
karakterleri bulur (ve yeni satır karakterini izleyen akut aksanı birleştirir) ve grep -Po '\X'
benim için grafik kümeleri bulur. Düzgün çalışması (veya denemesi grep -Po '(*UTF8)\X'
) için grep ve / veya PCRE'nin son sürümüne ihtiyacınız olabilir
Kutunuzda perl6 varsa :
$ perl6 -e 'for @*ARGS -> $w { .say for $w.comb }' 'cường'
c
ư
ờ
n
g
bulunduğunuz yerden bağımsız olarak çalışın.
Aşağıdakiler genel olacaktır:
$ awk -F '' \
'BEGIN { RS = ""; OFS = "\n"} {for (i=1;i<=NF;i++) $i = $i; print }' <file_name>
echo StackOver | sed -e 's/./&\n/g'
S
t
a
c
k
O
v
e
r
Özellikle bash'de bir cevap sorduğunuz için, bunu saf bash'da yapmanın bir yolu:
while read -rn1; do echo "$REPLY" ; done <<< "StackOver"
Bunun, " burada belge " nin sonundaki yeni satırı yakalayacağını unutmayın . Bundan kaçınmak, ancak yine de bash döngüsüne sahip karakterler üzerinde yineleme yapmak istiyorsanız printf
, yeni satırdan kaçınmak için kullanın .
printf StackOver | while read -rn1; do echo "$REPLY" ; done
Ayrıca Python 2 komut satırından kullanılabilir:
python <<< "for x in 'StackOver':
print x"
veya:
echo "for x in 'StackOver':
print x" | python
veya (1_CR tarafından yorumlandığı gibi) Python 3 ile :
python3 -c "print(*'StackOver',sep='\n')"
fold (1)
Komutu kullanabilirsiniz . Bu daha etkilidir grep
ve sed
.
$ time grep -o . <bigfile >/dev/null
real 0m3.868s
user 0m3.784s
sys 0m0.056s
$ time fold -b1 <bigfile >/dev/null
real 0m0.555s
user 0m0.528s
sys 0m0.016s
$
Önemli bir fark, katlamanın çıktıda boş satırlar üretmesidir:
$ grep -o . <(printf "A\nB\n\nC\n\n\nD\n")
A
B
C
D
$ fold -b1 <(printf "A\nB\n\nC\n\n\nD\n")
A
B
C
D
$
Çok baytlı karakterleri işleyebilirsiniz:
<input \
dd cbs=1 obs=2 conv=unblock |
sed -e:c -e '/^.*$/!N;s/\n//;tc'
Canlı girişle çalışırken oldukça kullanışlı olabilir, çünkü burada arabellek yoktur ve bir karakter bütün olduğu anda yazdırılır .
sed
komut içindir. şu an hakkında bir şey yazmam mümkün değil - oldukça uykulu im. yine de, bir terminali okurken çok kullanışlıdır.
dd
sed davranışı POSIX göre belirtilmemiş olacak böylece çıkış artık metin olmayacak şekilde, baytlı karakterleri kıracak.
Kelime sınırlarını da kullanabilirsiniz ..
$ perl -pe 's/(?<=.)(\B|\b)(?=.)/\n/g' <<< "StackOver"
S
t
a
c
k
O
v
e
r
Bash'da:
Bu, herhangi bir metinle ve yalnızca bash dahili ile (harici bir yardımcı program çağrılmaz) çalışır, bu nedenle çok kısa dizelerde hızlı olmalıdır.
str="Stéphane áàéèëêếe"
[[ $str =~ ${str//?/(.)} ]]
(set -- "${BASH_REMATCH[@]:1}"; IFS=$'\n'; echo "$*")
Çıktı:
S
t
é
p
h
a
n
e
á
à
é
è
ë
ê
ế
e
IFS'yi değiştirmek ve konum parametrelerini değiştirmek uygunsa, alt kabuk çağrısından da kaçınabilirsiniz:
str="Stéphane áàéèëêếe"
[[ $str =~ ${str//?/(.)} ]]
set -- "${BASH_REMATCH[@]:1}"
IFS=$'\n'
echo "$*"
s=stackoverflow;
$ time echo $s | fold -w1
s
t
a
c
k
o
v
e
r
real 0m0.014s
user 0m0.000s
sys 0m0.004s
güncellemeler burada hacky | en hızlı | pureBashBased yolu!
$ time eval eval printf \'%s\\\\n\' \\\${s:\{0..$((${#s}-1))}:1}
s
t
a
c
k
o
v
e
r
real 0m0.001s
user 0m0.000s
sys 0m0.000s
daha fazla şaşkınlık için
function foldh ()
{
if (($#)); then
local s="$@";
eval eval printf \'%s\\\\n\' \\\"\\\${s:\{0..$((${#s}-1))}:1}\\\";
else
while read s; do
eval eval printf \'%s\\\\n\' \\\"\\\${s:\{0..$((${#s}-1))}:1}\\\";
done;
fi
}
function foldv ()
{
if (($#)); then
local s="$@";
eval eval echo \\\"\\\${s:\{0..$((${#s}-1))}:1}\\\";
else
while read s; do
eval eval echo \\\"\\\${s:\{0..$((${#s}-1))}:1}\\\";
done;
fi
}
fold -b1
mi?
read -a var <<< $(echo "$yourWordhere" | grep -o "." | tr '\n' ' ')
bu, kelimenizi böler ve dizide saklar var
.
for x in $(echo "$yourWordhere" | grep -o '.')
do
code to perform operation on individual character $x of your word
done