Я подготовил эту таблицу со всеми возможными разрешениями и их практическими последствиями.
(*) Только имена файлов : другие атрибуты, такие как размер или дата, недоступны. Например. вы можете использовать клавишу табуляции для автозаполнения, но не команду ls.
Некоторые мысли :
Вы можете разбить графемы на кластеры вместо символов, если хотите печатать текст вертикально. Например, с e
с острым ударением:
С кластерами графема ( e
с его острым ударением будет один кластер графема):
$ Perl -CLAS -le 'for (@ARGV) {print for / \ X / g}' $ 'Ste \ u301phane'
S
t
é {{1} } p
h
a
n
e
(или grep -Po '\ X'
с GNU grep, созданный с поддержкой PCRE)
С символами (здесь с GNU grep
):
$ printf '% s \ n' $ 'Ste \ u301phane' | grep -o.
S
t
e
p
h
a
n
e
fold
предназначена для разбиения на символы, но GNU fold
не поддерживает многобайтовые символы, поэтому вместо этого разбивается на байты :
$ printf '% s \ n' $ 'Ste \ u301phane' | fold -w 1
S
t
e
�
�
p
h {{1} } a
n
e
На StackOver , который состоит только из символов ASCII (то есть один байт на символ, один символ на кластер графемы), все три дадут одинаковый результат.
Вы можете использовать команду fold (1)
. Она более эффективна, чем grep
и 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
$
Одно существенное отличие состоит в том, что fold будет воспроизводить пустые строки в выводе:
$ 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
$
Ниже будет общий:
$ awk -F '' \
'BEGIN { RS = ""; OFS = "\n"} {for (i=1;i<=NF;i++) $i = $i; print }' <file_name>
Вы также можете использовать границы слов ..
$ perl -pe 's/(?<=.)(\B|\b)(?=.)/\n/g' <<< "StackOver"
S
t
a
c
k
O
v
e
r
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
обновления вот хакерский | самый быстрый | способ на основе pureBash!
$ 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
для большего удобства
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
}
В bash:
Это работает с любым текстом и только с внутренними компонентами bash (внешняя утилита не вызывается), поэтому должна быть быстрой на очень коротких строках.
str="Stéphane áàéèëêếe"
[[ $str =~ ${str//?/(.)} ]]
(set -- "${BASH_REMATCH[@]:1}"; IFS=$'\n'; echo "$*")
Вывод:
S
t
é
p
h
a
n
e
á
à
é
è
ë
ê
ế
e
Если можно изменить IFS и изменить позиционные параметры, вы также можете избежать вызова вспомогательной оболочки:
str="Stéphane áàéèëêếe"
[[ $str =~ ${str//?/(.)} ]]
set -- "${BASH_REMATCH[@]:1}"
IFS=$'\n'
echo "$*"
for x in $(echo "$yourWordhere" | grep -o '.')
do
code to perform operation on individual character $x of your word
done
read -a var <<< $(echo "$yourWordhere" | grep -o "." | tr '\n' ' ')
это разделит ваше слово и сохранит его в массиве var
.
Использование Raku (, ранее известного как Perl _6)
~$ echo "StackOvér áàéèëêếe" | raku -ne '.chars.put;'
18
~$ echo "StackOvér áàéèëêếe" | raku -ne '.put for.comb;'
S
t
a
c
k
O
v
é
r
á
à
é
è
ë
ê
ế
e