Как выполнить итерации через несколько расширения файла, не заботясь о чувствительности к регистру?

[117730] Нет других недостатков, кроме того, что управление файлами и каталогами, как правило, более тонкое, а организация людей и групп может быть грязной.[12148]Поэтому ACL позволяет вам охватить любой сценарий, потому что он позволяет вам давать разрешения настолько тонко, насколько вы хотите, чтобы не было сценария, который может нарушить.[12149]В качестве резюме, большинство сценариев можно было бы охватить "традиционными" UNIX разрешениями. Когда вам нужно предоставить доступ к некоторым каталогам или файлам гетерогенным людям с гетерогенными ролями, ACL дает вам "золотую пулю", необходимую для этого. [117735]
1
23.07.2014, 08:34
3 ответа
[

] вместо этого используйте []zsh[]:[

] [
setopt extendedglob
for f ($arg/**/*.(#i)(txt|h|py)(N.)) {
  ...
}
] [
    ] [
  • ][]**/[]: любой уровень подкаталогов[
  • ] [
  • ][](#i)[] должен включать нечувствительное к регистру совпадение для остальной части глобуса (как []~(i)[] в []ksh93[]). [
  • ] [
  • ][](N.)[] является классификатором глобуса. []N[] должен не возвращать ошибку, если нет соответствующего файла и [].[] должен выбирать только обычные файлы (эквивалент [] найти [] -тип f[]-тип f[]))). Вы можете добавить туда []D[], чтобы также сопоставить точечные (скрытые) файлы и спуститься в скрытые папки (как []find[] по умолчанию).[
  • ] [
]
5
27.01.2020, 23:11

В bash можно установить nocaseglob:

shopt -s nocaseglob

for file in "$arg"/**/*.{txt,h,py}
do
  ....
done

shopt -u nocaseglob

noclaseglob можно использовать в любом bash, начиная с 2. 01, однако ** требует bash 4.0 или более поздней версии (и это следует за сим-связью до bash 4.3, где она была зафиксирована). Обратите внимание на исправление цитаты $arg, так как будут проблемы, если она содержит пробелы или глобусные символы.

Не используя ** вы можете сделать что-то вроде:

find "$arg" \( -iname '*.txt' -o -iname '*.h' -o -iname '*.py' \) -exec bash -c '
  for file; do
    ...
  done' bash {} +

Это найдет все файлы, которые вы ищете, и передаст их как отдельные аргументы новому экземпляру bash, который затем процитирует их. Если ваша операция для каждого файла - это одна команда, вы, вероятно, можете пропустить новый bash-объект и использовать эту команду напрямую.

Обновление

В соответствии с комментариями Стефана, приведенными ниже, совместимое с POSIX решение:

find "$arg" \( -name '*.[tT][xX][tT]' -o -name '*.[hH]' -o -name '*.[pP][yY]' \) \
  -exec sh -c '
  for file do
    ...
  done' sh {} +
6
27.01.2020, 23:11

Как насчет простого:

for file in "$(ls -1 | grep -iE '\.txt|\.py|\.h')";
do
  ....
done

Другой простой вариант:

find . -maxdepth 1 -iname '*.txt'; find . -maxdepth 1 -iname '*.py'; find . -maxdepth 1 -iname '*.h'; 

Вы можете оберните find в круглые скобки $() в bash, чтобы получить список.

2
27.01.2020, 23:11

Теги

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