Get grandparent directory in bash script - rename files for a directory in their paths

user1201155 picture user1201155 · Jan 21, 2014 · Viewed 9.4k times · Source

I have the following script, which I normally use when I get a bunch of files that need to be renamed to the directory name which contains them.

The problem now is I need to rename the file to the directory two levels up. How can I get the grandparent directory to make this work?

With the following I get errors like this example: "mv: cannot move ./48711/zoom/zoom.jpg to ./48711/zoom/./48711/zoom.jpg: No such file or directory". This is running on CentOS 5.6.

I want the final file to be named: 48711.jpg

#!/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
}

export -f dirnametofilename

find . -name "*.jpg" -exec bash -c 'dirnametofilename "{}"'  \;

find .

Answer

OnlineCop picture OnlineCop · Jan 22, 2014

Another method could be to use

(cd ../../; pwd)

If this were executed in any top-level paths such as /, /usr/, or /usr/share/, you would get a valid directory of /, but when you get one level deeper, you would start seeing results: /usr/share/man/ would return /usr, /my/super/deep/path/is/awesome/ would return /my/super/deep/path, and so on.

You could store this in a variable as well:

GRANDDADDY="$(cd ../../; pwd)"

and then use it for the rest of your script.