С zsh
иzmv
(для лучшего разрешения конфликтов):
autoload zmv
zmv -n '(**/)*.json(#qD.)' '$1$(jq -r '.billingAccountList[0]' < $f).json
(удалить -n
когда счастлив ).
С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
установлен ).