Сценарий Bash: разбиение слова на каждую букву

Я подготовил эту таблицу со всеми возможными разрешениями и их практическими последствиями.

linux directory permissions

(*) Только имена файлов : другие атрибуты, такие как размер или дата, недоступны. Например. вы можете использовать клавишу табуляции для автозаполнения, но не команду ls.

Некоторые мысли :

  • Когда X не установлен , R и W в основном бесполезны. Только
  • X отключение RW дает вам ложное ощущение безопасности, поскольку вы можете вслепую читать и записывать содержимое файла и получать доступ к подкаталогам. Вы должны быть уверены, что все прямые дочерние элементы каталога имеют явные разрешения.
  • В редких случаях вы будете использовать другие значения, кроме:
    • 0 : нет доступа.
    • 1 : минимальный доступ, разрешающий перемещение.
    • 5 : Разрешить чтение / запись, но не изменять структуру самого дерева каталогов.
    • 7 : Полный доступ.

17
25.07.2016, 15:30
10 ответов

Вы можете разбить графемы на кластеры вместо символов, если хотите печатать текст вертикально. Например, с 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 (то есть один байт на символ, один символ на кластер графемы), все три дадут одинаковый результат.

19
27.01.2020, 19:46

Если у вас есть perl6 в вашей коробке:

$ perl6 -e 'for @*ARGS -> $w { .say for $w.comb }' 'cường'       
c
ư
ờ
n
g

работает независимо от вашей локали.

6
27.01.2020, 19:46

Вы можете использовать команду 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
$ 
4
27.01.2020, 19:46

Ниже будет общий:

$ awk -F '' \
   'BEGIN { RS = ""; OFS = "\n"} {for (i=1;i<=NF;i++) $i = $i; print }' <file_name>
4
27.01.2020, 19:46

Вы также можете использовать границы слов ..

$ perl -pe 's/(?<=.)(\B|\b)(?=.)/\n/g' <<< "StackOver"
S
t
a
c
k
O
v
e
r
3
27.01.2020, 19:46
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
}
1
27.01.2020, 19:46

В 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 "$*"
2
27.01.2020, 19:46
for x in $(echo "$yourWordhere" | grep -o '.')
do
    code to perform operation on individual character $x of your word
done
1
27.01.2020, 19:46
read -a var <<< $(echo "$yourWordhere" | grep -o "." | tr '\n' ' ')

это разделит ваше слово и сохранит его в массиве var.

1
27.01.2020, 19:46

Использование 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

https://raku.org/

0
15.06.2021, 21:57

Теги

Похожие вопросы