2017-01-09 6 views
1

У меня есть файловая система с большим количеством файлов, которые я хочу использовать на компьютере с Windows. Нелегальные символы в именах файлов являются проблемой, поэтому я искал команду bash, которая рекурсивно санирует незаконные символы из всех файлов.Массовое переименование файлов с двойной цитатой в имени

Я нашел это решение (https://stackoverflow.com/a/19009177/7394134):

find . -name "*[<>:\\|?*]*" -exec bash -c 'x="{}"; y=$(sed "s/[<>:\\|?*]\+/-/g" <<< "$x") && mv "$x" "$y" ' \; 

Это делает работу штрафа для большинства файлов, но она не работает с файлами, содержащими двойные кавычки и выдает следующее сообщение об ошибке:

bash: (остальное имя файла после двойной кавычки): команда не найдена

Я нашел несколько разные вопросы, такие как «R эмулировать файлы, содержащие двойные кавычки "или" Удалить двойные кавычки с sed в файле ", но, к сожалению, я не смог перенести их решения на успешную модификацию вышеприведенной команды.

Примечание. Даже если могут быть однострочные линии, которые намного проще (я хотел бы их увидеть!), Я хочу понять эскапаж при передаче имен файлов через -exec в три команды, выполняемые bash , Можно ли создать команду, которая удаляет как двойные, так и одинарные кавычки таким образом?

ответ

0

Один из способов заключается в том, чтобы правильно скомпоновать все манипуляции в bash, включая command-substitution, то есть $(..). Не делать этого позволяет shell обрабатывать результат выполнения команды (если результат имеет пробелы/специальные символы) в виде отдельных слов. И если какая-либо из команд выполняется на результат, ошибки подвержены из-за неправильных аргументов (в вашем вероятном случае, вероятно, из-за неправильного присваивания по переменной y)

Итак, простой трюк, приведенный ниже, двойное цитирование вашего sed command like,

find . -name "*[<>:\\|?*]*" -exec bash -c 'x="{}"; y="$(sed "s/[<>:\\|?*]\+/-/g" <<< "$x")" && mv "$x" "$y" ' \; 

может сделать трюк для вас.

Или, если вы заинтересованы в более верном способе для обработки файлов со специальными символами в именах,

Используйте -print0 варианта в GNU find для обработки файлов со специальными-символами/белым-пространство в файловых именах, с bashprocess-substitution. Правильный сценарий будет

#!/bin/bash 

while IFS= read -r -d $'\0' file 
do 
    newfile="$(sed "s/[<>:\\|?*]\+/-/g" <<< "$file")" 
    mv -v -- "$file" "$newfile"  
done <(find . -name "*[<>:\\|?*]*" -print0) 

-print0 (a GNU find specific option) добавляет NULL символ в конце каждого файла/каталога, find команда возвращает так, чтобы обрабатывать имена с белыми-пространств/специальные-символов и read (-d$'\0'), расщепляет выход из find с \ 0 в качестве ограничителя.

Смежные вопросы