Как избежать ошибки при перечислении несуществующих файлов? - PullRequest
1 голос
/ 24 января 2020

Я группирую файлы по датам в именах файлов и обрабатываю их по группам.

for m in {01..12}; do
  for d in {01..31}; do
    f=`ls ./mydir/2018.${m}.${d}T*.jpg`
    # process files
  done
done

Однако код выдает ошибку, если в некоторые даты не существует файлов, например,

ls: невозможно получить доступ к '2018.01.20T * .jpg': такого файла нет или каталог

Как пропустить пропущенные даты?

Ответы [ 2 ]

4 голосов
/ 24 января 2020

Включить nullglob, чтобы несовпадающие символы подстановки расширялись до нуля. Затем вы можете пропустить синтаксический анализ ls всего и просто выполнить итерацию по соответствующим файлам.

shopt -s nullglob

for m in {01..12}; do
  for d in {01..31}; do
    for f in ./mydir/2018.${m}.${d}T*.jpg; do
      # process file
    done
  done
done

Если вам нужны все имена файлов одновременно, сохраните их в массиве . Массивы лучше, чем обычные строки, потому что они могут обрабатывать имена файлов с пробелами и другими специальными символами.

shopt -s nullglob

for m in {01..12}; do
  for d in {01..31}; do
    files=(./mydir/2018.${m}.${d}T*.jpg)
    # process files
    echo "processing ${files[@]}..."
  done
done

Какой самый чистый способ локализовать магазин, чтобы восстановить nullglob на его исходное (неизвестное) значение после этого блока?

Использовать подоболочку: заключить блок в скобки. Подоболочка создает дочерний процесс, который гарантирует, что изменения не попадут в родительский процесс.

(
    shopt -s nullglob
    ...
)

Это вежливо делать это всякий раз, когда вы изменяете параметры оболочки, и это элегантная альтернатива pushd + popd. Обратите внимание, что любые переменные будут локальными для подоболочки, поэтому будьте осторожны.

1 голос
/ 24 января 2020

Вот еще один способ, используя find:

Допустим следующий dir:

$ ls -l mydir/
total 0
-rw-r--r-- 1  0 Jan 23 16:46 2018.01.20Thellowet.jpg
-rw-r--r-- 1  0 Jan 23 16:47 2018.04.24Thellowet.jpg
-rw-r--r-- 1  0 Jan 23 16:46 some_random_crap
-rw-r--r-- 1  0 Jan 23 16:46 wet
-rw-r--r-- 1  0 Jan 23 16:46 when
-rw-r--r-- 1  0 Jan 23 16:46 who
-rw-r--r-- 1  0 Jan 23 16:46 wtf

Используя find:

find ./mydir/ -type f -regextype sed -regex ".*2018\.[0-9]\{,2\}\.[0-9]\{,2\}T.*\.jpg.*" -exec echo "---{}" \;

Дает (незначительная обработка данных добавление --- к имени файла):

---./mydir/2018.04.24Thellowet.jpg
---./mydir/2018.01.20Thellowet.jpg

ПРИМЕЧАНИЕ. При этом также будут возвращаться файлы с 2018.00.xy или 2018.xy.00, где x и y могут быть любым числом от 0 до 9


Regex объяснил:

.*: любой шаблон

[0-9]{,2}: число 2 git

Используется \ экранировать специальные символы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...