Как убедиться, что трехзначное имя файла содержит один из двух символов?

Так что мне нужно искать в каталоге файлы длиной 3 символа. Это легко, проблема в том, что как минимум 1 из 3 символов должен быть либо буквой «B», либо буквой «y». Я знаю, что [By] удостоверится, что символ является либо B, либо y, однако простого выполнения [By] [By] [By] будет недостаточно, поскольку не требуется, чтобы все 3 символа были либо B, либо y; только 1 из них должен быть. Пожалуйста, помогите.

2
задан 27 September 2013 в 13:15

3 ответа

Можно сделать соответствие шаблона в для цикла.

for file in ./???; do
    [[ -e $file && $file = *[By]* ]] || continue
    printf 'Do stuff with <%s>\n' "$file"
done

Или можно включить расширенные шарики путем выполнения shopt -s extglob. Затем можно использовать что-то как @([By]??|?[By]?|??[By])

shopt -s extglob
for file in ./@([By]??|?[By]?|??[By]); do
    [[ -e $file ]] || continue
    printf 'Do stuff with <%s>\n' "$file"
done

, Любой будет более эффективным, чем вовлечение grep.

, Если Вы пишете сценарий для POSIX sh, Вы могли бы сделать что-то вроде этого:

for file in ./???; do
    [ -e "$file" ] || continue
    case $file in 
        *[By]*) : ;;
        *) continue;;
    esac
    printf 'Do something with <%s>\n' "$file"    
done

Наконец, Вы могли использовать три шарика, хотя это выполнит итерации файлов в другом порядке, и Вы рискуете выполнять итерации того же файла многократно.

for file in ./[By]?? ./?[By]? ./??[By]; do
    [ -e "$file" ] || continue
    printf 'Do something with <%s>\n' "$file"    
done
2
ответ дан 27 September 2013 в 13:15
printf '%s\n' ??? | grep '[By]'

printf '%s\n' печать каждый аргумент передала ему, one-per-line; ??? шарик, который расширяется до каждого имени файла с тремя символами в рабочем каталоге. Это передается по каналу к grep, который печатает только те имена файлов, содержащие шаблон, Вы указали.

Между прочим, я использовал printf '%s\n' так то, что я вставил следующее мой ~/.bashrc для простоты:

alias necho='printf "%s\n"'  ##  newline-echo

Большую часть времени это будет прекрасно: это повредится на именах файлов, содержащих новые строки, но это довольно редко на самом деле (я только когда-либо видел их, когда я сделал их конкретно к моим сценариям тестирования). Вероятно, возможно сделать на скорую руку простое чистое решение для удара с помощью extglob, но Вы могли также использовать find работать вокруг этой проблемы:

find . -name '???' -a -name '*[By]*'

Это будет действовать рекурсивно по умолчанию; если Вы не хотите это, использовать -maxdepth 1.

find . -maxdepth 1 -name '???' -a -name '*[By]*'
2
ответ дан 27 September 2013 в 13:15

Попробуйте эту команду (команды):

cd /path/to/directory
ls | while read file; do if [ ${#file} -eq 3 ]; then echo $file; fi; done | grep '[By]'

или:

for file in ???; do echo $file; done | grep '[By]'

или, вариант без любого цикла:

ls | grep -ow '\w\{3\}' | grep '[By]'

ls перечислит все файлы из текущего каталога, затем мы выбираем только имена файлов, которые имеют точно 3 символа в длине и наконец, с помощью grep, мы выбираем только имена файлов, которые содержат B или y.

2
ответ дан 27 September 2013 в 13:15

Другие вопросы по тегам:

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