Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Is there any tool to urldecode a file's name and replace it?

Example:

$ ls
hello%20world.txt
$ urldecode *.txt
$ ls
hello world.txt
share|improve this question
up vote 1 down vote accepted

A new blog post covers this with echo(1) and printf(1).

urldecode() {
  arg="$1"
  i="0"
  while [ "$i" -lt ${#arg} ]; do
    c0=${arg:$i:1}
    if [ "x$c0" = "x%" ]; then
      c1=${arg:$((i+1)):1}
      c2=${arg:$((i+2)):1}
      printf "\x$c1$c2"
      i=$((i+3))
    else
      echo -n "$c0"
      i=$((i+1))
    fi
  done
}
share|improve this answer

sed and echo can urldecode a file's name like so:

$ echo -e "$(echo hello%20world+ok | sed 's/+/ /g;s/%\(..\)/\\x\1/g;s/\\x\(2[Ff]\)/%\1/g')"
hello world ok

We want this to be able to turn filenames into filenames, rather than pathnames (i.e., we don't want to add slashes), so we leave %2F alone.  (To be more precise, we turn \x2F back into %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\1/g;s/\\x\(2[Ff]\)/%\1/g')"
cat dog foo!"#$%&'()*+,-.%2Fbar

To actually rename files in the current directory:

$ ls *.txt
hello%20%20world++ok?.txt
$ for f in *.txt; do 
>   mv "$f" "$(echo -e "$(echo "$f" | sed 's/+/ /g;s/%\(..\)/\\x\1/g;s/\\x\(2[Ff]\)/%\1/g')")"
> done
$ ls *.txt
hello  world  ok?.txt

If the original (input) filenames contain backslashes, they will probably get mangled.

share|improve this answer
    
The idea here is to turn '+'s into spaces directly, and turn % signs into '\x' escapes, and then let echo interpret the \x escapes using the '-e' option. Try running "echo -e 'hello\x20world'" to see this in action. – Suppressingfire Nov 29 '09 at 15:35
    
How about the part where it renames the file(s)? – SamB Jun 1 '10 at 1:11
    
@SamB: left as an exercise for the reader :-) – Suppressingfire Jun 16 '10 at 20:29
    
Seems it doesn't work in all cases, filenames which fails: 10%20-%203%20-%20Model%20Selection%20and%20Train%2FValidation%2FTest%20Sets%20%‌​2812%20min%29.mp410%20-%203%20-%20Model%20Selection%20and%20Train%2FValidation%2F‌​Test%20Sets%20%2812%20min%29.mp4 or 10%20-%205%20-%20Regularization%20and%20Bias%2FVariance%20%2811%20min%29.mp410%‌​20-%205%20-%20Regularization%20and%20Bias%2FVariance%20%2811%20min%29 – kenorb Jul 15 '14 at 11:20

I think this Perl snippet can be used as a base for what you are looking for.

share|improve this answer

Type in shell (or add to .bashrc):

urldecode(){
    mv $1 "`echo $1 | xargs python -c "import urllib, sys; print urllib.unquote(sys.argv[1])"`"
}

Usage:

$ urldecode *.txt

Tested in bash, zsh. Credits.

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .