Сопоставление n-буквенного имени файла с ls

Сопоставление n-буквенного имени файла с ls

Я использую lsкоманду в bash, пытаясь найти все файлы или каталоги длины n. Допустим, n=5

Моя команда:

ls ?????

Но это также будет включать символы, которые не являются буквами, такие как точка. Например, следующие файлы будут соответствовать:

ab.cd    
abd.c

Мне нужно найти только файлы, имена которых состоят из 5 букв или цифр:

five1
five2    
five3

Но нет

abc.d    
ab.cd    
a.bcd

Как я могу изменить свою команду?

Ответ найден:

ls [a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]

Я нашел ответ, но как сделать это менее уродливым?

решение1

Обратите внимание, что это не lsто, что интерпретирует эти глобусы. Эти глобусы расширяются вашей оболочкой в ​​список имен файлов, который передается в качестве аргументов в ls. Разные оболочки имеют разные возможности глобализации. bashимеет несколько расширений по сравнению со стандартными глобусами (заимствованными из ksh88и включенными с помощью shopt -s extglob), но все еще ограничен по сравнению с такими оболочками, как zshили ksh93.

С zsh:

setopt extendedglob
ls -d [[:alnum:]](#c5)

ksh93:

ls -d {5}([[:alnum:]])

или:

ls -d {5}(\w) # (\w includes underscore in addition to alnums)

или, если вы хотите использовать расширенные регулярные выражения:

ls -d ~(E)^[[:alnum:]]{5}$

С помощью bashили других оболочек POSIX, не имеющих эквивалентных операторов подстановки, вам необходимо сделать следующее:

ls -d [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]

Обратите внимание, что [[:alnum:]]сюда входят любые алфавитные символы в текущей локали (не только латинские алфавиты, не говоря уже об английском) и 0123456789(и, возможно, другие типы цифр). Если вам нужны буквы английского алфавита, назовите символы по отдельности:

c='[0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]'
unset -v IFS
ls -d $c$c$c$c$c

Или используйте локаль C:

(export LC_ALL=C
ls -d [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]])

решение2

ls -q | grep -Ex '[[:alnum:]]{5}'

решение3

Если вы собираетесь использовать lsуказанным вами способом, вам следует использовать опцию -d; в противном случае будет выведен списоксодержаниелюбойкаталоги чьи имена состоят из пяти букв и/или цифр, а не перечисление самих имен. Также, вы можете сделать

ls -d [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]

но это ровно столько же текста, сколько и ответ, который вы получили сейчас.

Кроме того, если вы этого не сделаете,нуждатьсядля использования lsв вашей команде, вы можете использовать

echo [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]

который выведет список всех совпадений на одной строке, или

printf "%s\n" [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][:alnum:]]

который перечислит их в отдельных строках.

решение4

Постройте выражение в переменной:

 e=""; for m in $(seq 1 5); do e="$e[A-Za-z0-9]"; done

Поместите это в функцию, чтобы сделать ее более интересной/многоразовой:

 alnumglob() {
    local e=""
    for m in $(seq 1 $1) ; do e="$e[A-Za-z0-9]"; done
    echo "$e"
 }

 ls -ld $(alnumglob 5)

Связанный контент