简体   繁体   中英

Bash rename zips in subdirectories

Hi have a bunch of folders with one zip file in it the paths look like this

/folder/subfolder/archive.zip
/folder/subfolder1/archive1.zip
/folder/subfolder2/archive2.zip
/folder/subfolder3/zip3.zip
/folder/subfolder4/zip4.zip
etc...

I need the out put to be like this

/folder/subfolder/preview.zip
/folder/subfolder1/preview.zip
/folder/subfolder2/preview.zip
/folder/subfolder3/preview.zip
/folder/subfolder4/preview.zip
etc...

Each folder also only has one zip in it so i don't have to work about overwriting and what not i just need each zip in each folder renamed to preview.zip no matter the name in each subdirectory how can i do that in bash?

Thank you for any help

Something like this should do the job:

for j in **/*.zip; do mv "$j" "${j%/*.zip}/preview.zip"; done

As pointed out by SiegeX, note that to use recursive globbing you've got to set the globstar option and that is only available in bash 4.x

You can do this with Bash's parameter substitution:

bash-3.2$ for archive in folder/subfolder*/*.zip; do
    echo "Archive = ${archive}, Preview = ${archive%/*}/preview.zip"
done
Archive = folder/subfolder/archive.zip, Preview = folder/subfolder/preview.zip
Archive = folder/subfolder1/archive1.zip, Preview = folder/subfolder1/preview.zip
Archive = folder/subfolder2/archive2.zip, Preview = folder/subfolder2/preview.zip
Archive = folder/subfolder3/zip3.zip, Preview = folder/subfolder3/preview.zip
Archive = folder/subfolder4/zip4.zip, Preview = folder/subfolder4/preview.zip

Where ${archive%/*} will strip off everything from the last / in ${archive} .

This will allow you to verify the command that will run. Change this to:

mv "${archive}" "${archive%/*}/preview.zip" 

... to rename the files (even if they have whitespace in their names).

#!/bin/bash
while read file; do
  echo mv "$file" "${file%/*}/preview.zip"
done < <(find /folder -type f -name "archive*.zip")

Note : Remove the echo if the output looks sufficient and rerun the script to make the actual changes

This might work for you, but it's not fully tested:

find /folder -maxdepth 1 -mindepth 1 -type d -exec mv {}/archive*.zip {}/preview.zip \;

Working very strictly under your example, this should find all directories under /folder , with a maximum and minimum depth of 1 (ie only directories within /folder , since that seems to be what you want) and executes a mv command for a file under each.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM