С GNU Parallel это выглядит так:
locate -r "$PWD.*\.c$" | parallel 'test -f {} && echo "regular file"' | wc -l
Как видите, это очень похоже на вашу первоначальную попытку.
Если у вас менее 100 совпадений, вы можете использовать наборы GNU Parallel $? к количеству неудачных заданий до 100 (ЭТО НЕ МАСШТАБИРУЕТСЯ):
ls *txt | parallel \! test -f {}
echo $?
Если нужно еще быстрее:
locate -r "$PWD.*\.c$" |
perl -ne 'chomp; -l $_ or $s+= -f $_; END{print "$s\n"}'
Или комбинация:
locate -r "$PWD.*\.c$" |
parallel --block 10k --pipe -q perl -ne 'chomp; -l $_ or $s+= -f $_; END{print "$s\n"}' |
awk '{s+=$1} END {print s}'
При этом будут найдены и переименованы все файлы «*.pdf» в текущем каталоге, имена которых следуют за шаблон, описанный в вопросе с тем же именем, но с номером дополнен до 2 цифр:
#!/usr/bin/env bash
shopt -s nullglob
for f in *[[:space:]][0-9].pdf; do
int="$(basename "$f" | rev | cut -d ' ' -f1 | rev | cut -d. -f1)"
name="$(basename "$f" | rev | cut -d ' ' -f2- | rev)"
padded_int="$(printf "%02d\n" "$int")"
echo mv "$f" "$(printf "%s %s.pdf" "$name" "$padded_int")"
done
Удалите echo
перед mv
, чтобы фактически запустить mv
, но сначала запустите его как есть чтобы убедиться, что он делает то, что вы хотите. Пример использования с приведенный выше скрипт сохранен вpdf.sh
:
$ for i in {1..10}; do touch "C Block Scan copy $i.pdf"; done
$./pdf.sh
mv C Block Scan copy 1.pdf C Block Scan copy 01.pdf
mv C Block Scan copy 2.pdf C Block Scan copy 02.pdf
mv C Block Scan copy 3.pdf C Block Scan copy 03.pdf
mv C Block Scan copy 4.pdf C Block Scan copy 04.pdf
mv C Block Scan copy 5.pdf C Block Scan copy 05.pdf
mv C Block Scan copy 6.pdf C Block Scan copy 06.pdf
mv C Block Scan copy 7.pdf C Block Scan copy 07.pdf
mv C Block Scan copy 8.pdf C Block Scan copy 08.pdf
mv C Block Scan copy 9.pdf C Block Scan copy 09.pdf
Первая строка:
#!/usr/bin/env bash
это шебанг . Кроме того, я использую env
для его особенности .
Эта строка
shopt -s nullglob
устанавливает nullglobоболочка опция что также объясняется на связанном сайте:
nullglob
If set, Bash allows filename patterns which match no files to
expand to a null string, rather than themselves.
Необходимо предотвратить запуск цикла for при отсутствии файлов которые соответствуют критериям шаблона:
for f in *[[:space:]][0-9].pdf; do
*[[:space:]][0-9].pdf
- это шаблон оболочки, который означает поиск файлов которые имеют имена, состоящие из любого количества символов, за которыми следует пробел, за которым следует одна цифра и конец .pdf . Внутри цикл $f
будет содержать имя обработанного файла.pdf.
Здесь
int="$(basename "$f" | rev | cut -d ' ' -f1 | rev | cut -d. -f1)"
используем команду замена присвоить целой части заданного имени файла переменной.Ты сможешь посмотреть, что basename
делает в man basename
, и воспроизвести конвейер в терминале:
$ f='C Block Scan copy 1.pdf'
$ echo basename "$f" | rev | cut -d ' ' -f1 | rev | cut -d. -f1
1
$ f='C Block Scan copy 5.pdf'
$ echo basename "$f" | rev | cut -d ' ' -f1 | rev | cut -d. -f1
5
(Обратите внимание, что $
здесь находится командная строка подсказка используется для обозначения начала новой строки, а не части команды ).
В следующей строке
name="$(basename "$f" | rev | cut -d ' ' -f2- | rev)"
мы извлекаем часть имени из.pdf, то есть все до количество.
В следующей строке
padded_int="$(printf "%02d\n" "$int")"
мы используем Bash, встроенный -в команду printf
, чтобы заполнить $int
и сохранить его в переменная с именем padded_int
. В последней строке цикла
echo mv "$f" "$(printf "%s %s.pdf" "$name" "$padded_int")"
мы запускаем (без echo
конечно )фактическое переименование с использованием printf
и снова подмена команды. printf
используется с форматом 2 %s
спецификаторы и 2 соответствующих аргумента, аналогично C.
Последняя строка
done
закрывает цикл.
zsh
(теперь является пользовательской оболочкой по умолчанию в macOS):
autoload zmv # best in ~/.zshrc
zmv '(* )([0-9].pdf)' '${1}0$2'
Использование P.E. расширение параметра. Только mv
для внешних инструментов из оболочки bash
.
#!/usr/bin/env bash
shopt -s nullglob
for f in *[[:space:]][0-9].pdf; do
n=${f##* } ##: Remain only 1.pdf, 2.pdf etc.
n=0${n%.*} ##: Remain only 1, 2 etc. and pad 0 so it will be 01, 02..
echo mv -v "$f" "${f/[0-9]/"$n"}" ##: Replace all [0-9] with the value of "$n"
done