Переименование серии файлов
Вопрос
Пытаюсь переименовать серию файлов на Linux-сервере.Найти нужные файлы легко:
find . -type f -wholename \*.mbox
Конечно, поскольку некоторые из них являются файлами mbox, в именах есть пробелы, поэтому получается:
find . -type f -wholename \*.mbox -print0
Я подключаюсь к xargs, чтобы переименовать файлы:
find . -type f -wholename \*.mbox -print0 | xargs -0 -I{} echo ${"{}"/.mbox/}
Эхо должно возвращать что-то вроде INBOX, учитывая INBOX.mbox, однако bash жалуется:
bash: ${"{}"/.mbox/}: bad substitution
Как я могу это исправить?Я бы хотел попытаться сохранить его в решении find/xargs, если это возможно, чтобы не добавлять вокруг него много циклических конструкций.
Решение
Пытаться
find . -type f -wholename \*.mbox | sed 's/\(.*\)\.mbox/mv "\1.mbox" "\1"/' | sh
Это не 100% защита от дурака, если некоторые файлы содержат символы двойных кавычек, но я полагаю, вы можете это игнорировать :)
Другие советы
GNU Parallel http://www.gnu.org/software/parallel/ имеет {.}, который удаляет расширение:
find . -type f -wholename \*.mbox -print0 | parallel -0 mv {} {.}
Если вы знаете, что имена файлов не содержат \ n, тогда это будет работать также:
find . -type f -wholename \*.mbox | parallel mv {} {.}
Я думаю, тебе это нужно:
find . -wholename \*.mbox | awk '{new=<*>; gsub("\.mbox<*>quot;, "", new) ; system("mv \"" <*> "\" \"" new "\"") }'
(должен быть совместим с gawk и mawk, протестирован на mawk). Он не использует xargs, но учтите, что он не создает новый процесс для каждого перемещенного файла. Если вам нужно переместить большое количество файлов, вы заметите преимущество. Предупреждение: если какой-либо из файлов будет содержать новую строку в названии, у вас возникнут проблемы (но если это проблема, Бог с вами).
Вы дополнительно улучшаете это решение, используя xargs для удаления нескольких файлов за один вызов rm
.
Если вам действительно нужна скорость, я бы предложил вам использовать скрипт на python вместо awk. Это сделает все rm
без единой вилки.
Не могли бы вы использовать переименование (1)? Поставляется с Perl.
Вы можете попробовать:
find . -type f -wholename \*.mbox -print0 | sed 's/\.mbox//'
Ваша проблема в том, чтобы попытаться отправить в xargs. К этому моменту " {} "
ничего не значит.
Чтобы переименовать файлы (при условии, что вы находитесь под Bash)
find . -type f -wholename \*.mbox -print0 | \
while read I ; do
mv $I $(echo $I | sed 's/\.mbox//') ;
done ;
Вот, пожалуйста, это должно сработать ....
# find .
.
./test.tst
./test1.tst
./test2.tst
./test/test4.tst
./test/test5.tst
#
for file in `find . -type f`
do
mv $file ${file%.tst}.new
done
# find .
.
./test
./test/test4.new
./test/test5.new
./test1.new
./test2.new