Need loop to delete parts of file name - shell

I have been using an image optimizer for my websites and when I do this, it gives me files with -compressor at the end of it.
input: filename.jpg
output: filename-compressor.jpg
I need help in creating a batch file or a command script that I can just place these files into a folder and it will loop through all of these and change the names of these for me so that I don't have to go through them one by one.

mkdir -p compressors
mv *-compressor.jpg compressors/
cd compressors
for i in *-compressor.jpg; do j=${i%%\-compressor.jpg}.jpg; mv "$i" "$j"; done

Related

How do I Batch Rename Folders in OSX?

So I have been trying to rename about 5000 folders based on a CSV (Old name, Newname)
This is a one time operation, once hdkjsh2-2f8c-46b9-bbdb_doc is converted to 3 then it will not need to be touched again.
I have tried the solution here (Setting up an automator workflow with a command script) but found that it does not do a great deal when it comes to folder/directory names and all the guides/documentation is around file names and not folder.
Any suggestions would be much appreciated
Example of CSV
Doc_Location, New_ID
hdkjsh2-2f8c-46b9-bbdb_doc , 3
Please make a backup before trying the following.
Save the following script in your HOME directory as renamer:
#!/bin/bash
cat "file.csv" | while IFS=' ,' read dir new ; do
if [ -d "$dir" ]; then
echo Rename $dir as $new
#mv "$dir" "$new"
else
echo "ERROR: Directory $dir not found - ignored"
fi
done
Then start Terminal and make the script executable by running:
chmod +x $HOME/renamer
Then change directory to where your directories are that need renaming:
cd path/to/things/needing/renaming
Make sure you have your CSV, called file.csv saved in that directory, then run with:
$HOME/renamer
It doesn't actually do anything, it just tells you what it would do. If it looks correct, edit $HOME/renamer and remove the single # on the line that says:
#mv "$dir" "$new"
so that is looks like:
mv "$dir" "$new"
Then be doubly sure you have made a backup and run the script again:
$HOME/renamer
Go to the folder where the other folders you want to rename are located. Select all the folders you want to rename. Then click on the action icon at the top of finder window. This will open a window where one option is to rename x items. See image below.
When you select "Rename x items" you get a box like the one shown below where you can specify the new names.

Bash - Moving files from subdirectories

I am relatively new to bash scripting.
I need to create a script that will loop through a series of directories, go into subdirectories with a certain name, and then move their file contents into a common folder for all of the files.
My code so far is this:
#!/bin/bash
#used to gather usable pdb files
mkdir -p usable_pdbFiles
#loop through directories in "pdb" folder
for pdbDirectory in */
do
#go into usable_* directory
for innerDirectory in usable_*/
do
if [ -d "$innerDirectory" ] ; then
for file in *.ent
do
mv $file ../../usable_pdbFiles
done < $file
fi
done < $innerDirectory
done
exit 0
Currently I get
usable_Gather.sh: line 7: $innerDirectory: ambiguous redirect
when I try and run the script.
Any help would be appreciated!
The redirections < $innerDirectory and < $file are invalid and this is causing the problem. You don't need to use a loop for this, you can instead rely on the shell's filename expansion and use mv directly:
mkdir -p usable_pdbFiles
mv */usable_*/*.ent usable_pdbFiles
Bear in mind that this solution, and the loop based one that you are working on, will overwrite files with the same name in the destination directory.

Bash If then that reads a list in a file condition

Here is the condition:
I have a file with all packages installed.
I have a folder with all kinds of other packages, but they include all of the ones in the list, plus more.
I need a bash script that will read the file and check a folder for packages that don't exist in the list then remove them, they are not needed, but keep the packages that are on the list in that folder.
Or perhaps the bash should read folder then if packages in the folder aren't on the list them rm -f that or those packages.
I am familiar with writing if then conditional statements, I just don't know how to do if making the items in the list a variable or variables (in a loop).
thanks!
I would move the packages on the list to a new folder, delete the original folder, and move the temporary folder back:
DIR=directory-name
mkdir "$DIR-tmp"
while read pkgname; do
if [[ -f "$DIR/$pkgname" ]]; then
mv "$DIR/$pkgname" "$DIR-tmp"
fi
done < package-list.txt
# Confirm $DIR-tmp has the files you want first!
rm -rf "$DIR"
mv "$DIR-tmp" "$DIR"
I think you want something like this:
for file in $(ls folder) ; do
grep -E "$file" install-list-file >/dev/null || \
echo $file
done > rm-list
vi rm-list # view file to ensure correct
rm $(<rm_list)
There are ways to make this faster (using parameter substitution to avoid fork/exec's), but I recommend avoiding fancy shell stuff [${file##*/}] until you've got the basics down. Also, this script basically translates the description into a script and is not intended to be much more than a guide on how to approach the problem.

Loop to unzip from one directory to individual directories

I am trying to design a loop that implements a lot of single elements I have seen before and the combination is throwing me off. Basically I have a structure like this:
/bin/script.sh
/conf/patches/1.zip
/conf/patches/2.zip
/conf/patches/3.zip
/sharedir
I want a loop that will go through however many patches I have in /conf/patches, unzip each patch into a separate directory in /sharedir. Each directory should be named the name of the file.
What I was trying so far was:
for file in '../conf/patches/*.zip'
do
unzip "${file%%.zip}" -d /sharedir/$file
done
As you can see...there is definitely something I am missing in this combination.
Try this:
for file in /conf/patches/*.zip
do
f="${file##*/}"
mkdir -p "/sharedir/${f%.zip}"
unzip -d "/sharedir/${f%.zip}" "${file}"
done
Remove quotes from glob pattern otherwise it is not expanded:
for file in ../conf/patches/*.zip
do
unzip "${file%%.zip}" -d /sharedir/
done
EDIT: You can try
for f in ../conf/patches/*.zip; do
echo g="${f%%/*}"
unzip -d "sharedir/${g%*.zip}" "$f"
done

Automator bash unix script, read input files to move if single file or detect if multiple archive and then move archive

I have a droplet made with automator, which moves files when I drop them on application icon to certain folder.
now script looks like this:
for f in "$#"
do
cp "$f" "volumes/testdrive/testfolder/$(basename "$f")"
done
I was wondering if it possible to do command to detect if multiple files were input into script and then archive them with zip function and move to same folder, and if single file was dropped do regular copy of file to specified folder.
Use a conditional, something like (syntax might be way off):
if [ $# > 1 ]
then zip $# > /path/to/location/foo.zip # this line might need to be researched
else cp $# /path/to/location/`basename $#`
fi
You wouldn't want to do this with a for loop, because then it'd go through the rigmarole of creating a zip archive for each file in the selection. If what you were doing was moving each one, then sure, use a loop, but you're just taking them all and zipping them
$# contains the number of arguments passed to the script.

Resources