Когда я столкнулся с ошибкой, я запустил сценарий с помощью sudo, поскольку от него зависели другие части сценария. Как ни странно, он отлично работает, если я запускаю часть proxychains без sudo... Думаю, я как-то испортил права пользователя.
Просто используйте zsh
сzmv
:
#! /bin/zsh -
autoload -Uz zmv
zmv '(**/)(* *)' '$1${2// /_}'
zmv
по умолчанию пропускает скрытые файлы и файлы в скрытых каталогах (, если вы не передадите квалификатор (#qD)
в первый аргумент ), sort -rz
не гарантирует работу для этого и -prune
не совместим с-depth
)dirname
/ basename
(, что было бы дорого и не работало бы должным образом с подстановкой команд, если есть некоторые имена файлов, заканчивающиеся символами новой строки ). find
проблем, из-за которых *
не совпадают произвольные последовательности байтов. a b c
и a_b c
, которые оба будут переименованы в a_b_c
), он обнаружит это в начале и прервется, прежде чем выполнять какое-либо переименование. Чтобы сделать что-то похожее с инструментами GNU, это будет что-то вроде:
#! /bin/bash -
export LC_ALL=C
while IFS= read <&3 -rd '' file; do
dir=${file%/*} name=${file##*/}
mv -i -- "$file" "$dir/${name// /_}"
done 3< <(
find. -name '.?*' -prune -o -name '* *' -print0 |
tac -s '')
Вот,
C
, чтобы *
соответствовала любой последовательности байтов, а не только тем, которые образуют допустимые символы в локали пользователя. Имейте в виду, однако, что сообщения (, ошибки, подсказки... )будут выдаваться на английском, а не на языке пользователя. -i
на mv
для защиты от непреднамеренного затирания файлов. mv -i
работает. tac -s ''
вместо sort -rz
для реверсирования вывода, чтобы обеспечить переименование листьев перед ветвями, на которых они находятся. dirname
/ basename
стандартными операторами раскрытия параметров ${var##pattern}
и ${var%pattern}
. -r
в read
, чтобы отключить специальную обработку обратной косой черты. read
$IFS
пусто, поэтому он не удаляет конечные пробелы из входных записей.