samoot04
samoot04

Reputation: 41

Renaming ZIP files according to the parent directory name

For a number of files I want to get the parent directory and append its name to the filename. For example, in the following path:

A/B/C/file.zip

I want to rename file.zip to file_C.zip.

Here is my code. I have to find directory which does not contain subdirectory and zip files in it, and I want to rename it to refer to the parent directory.

find ${WORKDIR} -daystart -mtime +3 -type d -links 2 -exec bash -c 'zip -rm "${1%}".zip "$1"' _ {} \;

Upvotes: 0

Views: 795

Answers (2)

Ruslan Osmanov
Ruslan Osmanov

Reputation: 21492

Here is a pure Bash solution:

find "$WORKDIR" -type f -name '*.zip' | while read file
do
  basename=$(basename "$file")
  dirname=$(dirname "$file")
  suffix=$(basename "$dirname")
  if [[ "$basename" != *"_${suffix}.zip" ]]; then
    mv -v "$file" "${dirname}/${basename%.zip}_${suffix}.zip"
  fi
done

The script processes all *.zip files found in $WORKDIR with a loop. In the loop it checks whether $file already has a suffix equal to the parent directory name. If it hasn't such suffix, the script renames the file appending "_{parent_directory_name}" to the filename just before the extension.

Sample Tree

A
├── B
│   ├── abc.zip.zip
│   └── C
│       └── file_C.zip
└── one.zip

Sample Output

‘./t/A/one.zip’ -> ‘./t/A/one_A.zip’
‘./t/A/B/abc.zip.zip’ -> ‘./t/A/B/abc.zip_B.zip’

A
├── B
│   ├── abc.zip_B.zip
│   └── C
│       └── file_C.zip
└── one_A.zip

where WORKDIR=./t.

Note, I deliberately simplified the find command, as it is not important for the algorithm. You can adjust the options according to your needs.

Upvotes: 2

zwol
zwol

Reputation: 140559

The best tool for this job is the rename utility that comes with Perl. (Beware that util-linux also contains a utility named rename. It is not what you want. If you have that on your system, investigate how to get rid of it and replace it with the one that comes with Perl.)

With this utility, it's as simple as

find $WORKDIR -name '*.zip' -exec \
    rename 's:/([^/]+)/(.+?)\.zip$:/${2}_${1}.zip:' '{}' +

You can stick arbitrary Perl code in that first argument, which makes it even more powerful than it looks from this example.

Note that your find command appears to do something unrelated, involving the creation of .zip files.

Upvotes: 0

Related Questions