Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a bunch of files each in their own subdirectory. I need to write a script to rename each file to have the same name as its directory: For example, given:

./1111/1234.pdf
./2222/2345.pdf
./1234/3214.pdf

I need them to be renamed to:

./1111/1111.pdf
./2222/2222.pdf
./1234/1234.pdf

How can I do that?

share|improve this question
    
Doesn't happen to be homework? –  Hauke Laging Jun 10 '13 at 20:36

3 Answers 3

up vote 4 down vote accepted

Assuming your shell is zsh, put autoload -U zmv in your ~/.zshrc, and run

zmv '(*)/*.pdf' '$1/$1.pdf'
share|improve this answer

The following bash script does the job when invoked in the parent directory. It does so even when the files don't all have the same extension (they do in your limited example, but that might be a coincidence):

#!/bin/bash
function dirnametofilename() {
  for f in $*; do
    bn=$(basename "$f")
    ext="${bn##*.}"
    filepath=$(dirname "$f")
    dirname=$(basename "$filepath")
    mv "$f" "$filepath/$dirname.$ext"
  done
}

dirnametofilename ./????/*

the invocation there assumes any file in a subdirectory of the current directory which has a name with four characters. You can exchange the last line with:

dirnametofilename $*

and specify the filenames as parameters to the script


The following creates a somewhat deeper hierarchy and uses find to locate the files. The export -f make sure the bash started by find knows about the function:

mkdir -p x/y/z/1111 x/y/z/2222 x/y/z/1234
touch x/y/z/1111/1234.pdf
touch x/y/z/2222/2345.pdf
touch x/y/z/1234/3214.pdf

function dirnametofilename() {
  for f in $*; do
    bn=$(basename "$f")
    ext="${bn##*.}"
    filepath=$(dirname "$f")
    dirname=$(basename "$filepath")
    mv "$f" "$filepath/$dirname.$ext"
  done
}

export -f dirnametofilename

find . -name "*.pdf" -exec bash -c 'dirnametofilename "{}"'  \;
# and look at the result
find x
share|improve this answer
    
what if you need to run this in directory x from:/x/y/z/1111/1234.pdf –  Duy Jun 13 '13 at 12:23
    
just feed the function the whole path y/z/1111/1234.pdf it will rename to y/z/1111/1111.pdf. Use e.g. find to locate the files (echo first to see if you got the right set of names, then subsitute the echo with the function call). –  Anthon Jun 13 '13 at 12:58
    
@duy extended the answer, hope you can get it to work this way. –  Anthon Jun 13 '13 at 13:14
echo ./1111/1234.pdf | perl -pe '$_.=$_; s/\/(.*?)\/.+\.(.*?)$/\/$1\/$1\.$2/' | xargs -n 2 mv
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.