Как избежать спецсимволов? - PullRequest
2 голосов
/ 30 марта 2012

Я пытаюсь удалить песни через оболочку bash для цикла, но удаляю такой файл, как этот

while read item; do rm "$item"; done < duplicates

продолжает увлекаться названием песни. Можно ли обойти это? Названия моих песен могут выглядеть так:

/home/user/Music/Master List's Music/iTunes/iTunes\ Music/John\ Mayer/Room\ for\ Squares\ \[Aware\]/07\ 83.m4a
/home/user/Music/Master List's Music/bsg\ season\ 1\ \(Case\ Conflict\ 1\)/06\ A\ Good\ Lighter.mp3
/home/user/Music/Master List's Music/Nino\ Rota/The\ Godfather\ Pt.\ 3/14\ A\ Casa\ Amiche.m4a

Как видите, для удаления элемента у меня не может быть%. () [] Или чего-либо еще, без экранирования, если это не. перед расширением файла очевидно. Есть ли способ, которым я могу избежать специальных символов, как это?

Например, я использовал sed, чтобы превратить% 20 ​​в пробелы:

cat duplicates | sed 's/%20/\\ /g' > clean_duplicates

Вывод, который я ищу, выглядит следующим образом:

/home/user/Music/Master\ List\'s\ Music/iTunes/iTunes Music/John\ Mayer/Room\ for\ Squares\ \[Aware\]/07\ 83.m4a
/home/user/Music/Master\ List\'s\ Music/bsg\ season\ 1\ \(Case\ Conflict\ 1\)/06\ A\ Good\ Lighter.mp3
/home/user/Music/Master\ List\'s\ Music/Nino\ Rota/The Godfather\ Pt\.\ 3\/14\ A\ Casa\ Amiche.m4a

1 Ответ

2 голосов
/ 30 марта 2012

Обновление Чтобы обратиться к фактическому декодированию url (я пропустил это раньше):

while read line; do printf "$(echo -n $line | sed 's/\\/\\\\/g;s/\(%\)\([0-9a-fA-F][0-9a-fA-F]\)/\\x\2/g')\n"; done < input

Вывод:

/home/user/Music/Master List's Music/iTunes/iTunes Music/John Mayer/Room for Squares [Aware]/07 83.m4a
/home/user/Music/Master List's Music/bsg season 1 (Case Conflict 1)/06 A Good Lighter.mp3
/home/user/Music/Master List's Music/Nino Rota/The Godfather Pt. 3/14 A Casa Amiche.m4a

Так, чтобы удалить тефайлы, например, перенаправить очищенный вывод в файл:

while read line
do 
    printf "$(echo -n $line | sed 's/\\/\\\\/g;s/\(%\)\([0-9a-fA-F][0-9a-fA-F]\)/\\x\2/g')\n"
done < duplicates > cleaned_duplicates

while read file; do rm -v "$file"; done < cleaned_duplicates

Если вы предпочитаете сохранять имена в файлах сценариев, используя явный экранирующий символ оболочки, вы можете сделать

while read file; do printf "rm -v %q\n" "$file"; done < cleaned_duplicates > script.sh

Что должно привести к script.sh, содержащему:

rm -v /home/user/Music/Master\ List\'s\ Music/iTunes/iTunes\ Music/John\ Mayer/R
rm -v /home/user/Music/Master\ List\'s\ Music/bsg\ season\ 1\ \(Case\ Conflict\ 
rm -v /home/user/Music/Master\ List\'s\ Music/Nino\ Rota/The\ Godfather\ Pt.\ 3/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...