sed
e echo
podem urldecode o nome de um arquivo da seguinte forma:
$ echo -e "$(echo hello%20world+ok | sed 's/+/ /g;s/%\(..\)/\x/g;s/\x\(2[Ff]\)/%/g')"
hello world ok
Queremos que isso seja capaz de transformar nomes de arquivos em nomes de arquivos,
em vez de nomes de caminhos (ou seja, não queremos adicionar barras),
então deixamos %2F
sozinho.
(Para ser mais preciso, transformamos \x2F
de volta em %2F
.)
$ echo -e "$(echo cat+dog%20foo%21%22%23%24%25%26%27%28%29%2A%2B%2C%2D%2E%2Fbar |
sed 's/+/ /g;s/%\(..\)/\x/g;s/\x\(2[Ff]\)/%/g')"
cat dog foo!"#$%&'()*+,-.%2Fbar
Para renomear arquivos no diretório atual:
$ ls *.txt
hello%20%20world++ok?.txt
$ for f in *.txt; do
> mv "$f" "$(echo -e "$(echo "$f" | sed 's/+/ /g;s/%\(..\)/\x/g;s/\x\(2[Ff]\)/%/g')")"
> done
$ ls *.txt
hello world ok?.txt
Se os nomes de arquivo originais (entrada) contiverem barras invertidas,
eles provavelmente serão mutilados.