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 stringgrosso 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).
sedgibi 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 ( eakut 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
foldkarakterleri 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 -Pobiri beklendiği gibi grep -Pyapmaz (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 grepve 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 .
sedkomut 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.
ddsed 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 -b1mi?
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