Так что мне нужно искать в каталоге файлы длиной 3 символа. Это легко, проблема в том, что как минимум 1 из 3 символов должен быть либо буквой «B», либо буквой «y». Я знаю, что [By] удостоверится, что символ является либо B, либо y, однако простого выполнения [By] [By] [By] будет недостаточно, поскольку не требуется, чтобы все 3 символа были либо B, либо y; только 1 из них должен быть. Пожалуйста, помогите.
Можно сделать соответствие шаблона в для цикла.
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
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]*'
Попробуйте эту команду (команды):
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
.