Создать папку на основе имени файла

С zshиzmv(для лучшего разрешения конфликтов):

autoload zmv
zmv -n '(**/)*.json(#qD.)' '$1$(jq -r '.billingAccountList[0]' < $f).json

(удалить -nкогда счастлив ).

0
23.08.2020, 01:14
1 ответ

Сzsh:

#! /bin/zsh -
() { mkdir -p -- ${(u)argv%%( <->|).png}; } *.png

Где:

  • () { code; } arguments— это анонимная функция, которая принимает список не -скрытых .pngфайлов в текущем каталоге в качестве аргументов (, доступных как $argvили $@вcode).
  • <->— это оператор zsh glob, который соответствует любой последовательности десятичных цифр (<first-last>, где ни first, ни lastне указаны ).
  • ${(u)array-expansion}расширяется до уникальных элементов (удаляет дубликаты )расширения массива.
  • ${array%%pattern}расширяется до элементов массива, лишенных самой длинной строки в конце, которая соответствует pattern.

Итак, здесь мы создаем каталог для каждой уникальной строки, состоящей из файлов png, лишенных необязательного " <digits>", за которым следует .png.

С помощью bashи инструментов GNU вы можете сделать что-то подобное с:

#! /bin/bash -
export LC_ALL=C # needed for sed to deal with arbitrary byte values, for
                # [0-9] to match on 0123456789 only and for sort -u to report
                # unique records as opposed to one of several that sort the
                # same.

shopt -s failglob # to properly handle the cases where there's no png
set -o pipefail   # ditto, to report a failure exit status in that case.

printf '%s\0' *.png |
  sed -Ez 's/( [0-9]+)?\.png$//' |
  sort -zu |
  xargs -r0 mkdir -p --

Или избегать GNU-измов и использовать bash 4+:

#! /bin/bash -
shopt -s failglob extglob
typeset -A unique
files=(*.png) || exit
for file in "${files[@]}"; do
  file=${file%.png}
  file=${file% +([0123456789])}
  unique[$file]=
done
mkdir -p -- "${!unique[@]}"

Обратите внимание, что если в текущем каталоге есть файл с именем " 12.png", это приведет к пустому имени каталога. В этом последнем bashрешении выше это вызовет синтаксические ошибки, поскольку bashассоциативные массивы не поддерживают элементы с пустым ключом, а во всех остальных вы получите ошибку mkdir, которая не будет возможность создать каталог с пустым именем.

Обратите внимание, что macos не поставляется с инструментами GNU по умолчанию и поставляется с очень старой версией bash. Однако он всегда шел с zsh. Если вам нужно использовать bashтам и вы не можете установить более новые версии или инструменты GNU, вы можете вместо этого прибегнуть к perl:

#! /bin/bash -
perl -e '
  for (<*.png>) {
    s/\.png\z//;
    s/ \d+\z//;
    $unique{$_} = undef;
  }
  $ret = 0;
  for (keys %unique) {
    unless (mkdir($_) || ($!{EEXIST} && -d $_)) {
      warn "Cannot create $_: $!\n";
      $ret = 1;
    }
  }
  exit $ret;'

(хотя в этом коде нет ничегоbash-конкретного, который должен работать с shлюбой системы при условии, что perlустановлен ).

1
18.03.2021, 23:10

Теги

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