Bash get list of zip files in dir and perform some operations on each of them - bash

I have a bash script, which goes through list of directories and if some directory contains zip files it bind zip file name into variable and perform some actions over it and then goes to another in this dir. Unfortunately, it works when there is one zip file per directory. If more - it gives error "Binary operator expected"
Script:
if [ -e $currdir/*.zip ]; then
for file in $currdir/*.zip; do
echo the zip is "${file##*/}"
done
Please help me to rework script accordingly.

If you need exactly check then you can use:
if [[ -n $(echo "$currdir"/*.zip) ]]; then
for f in "$currdir"/*.zip; do
echo "Processing $f file..";
done
fi
But I'd prefer just looping over files that contain *.zip extension:
for f in "$currdir"/*.zip; do
echo "Processing $f file..";
done

Use
for file in "$currdir"/*.zip; do
[ -e "$file" ] || continue
echo the zip is "${file##*/}"
done
As pointed out in the comments the glob will happen in the shell, then [ is called with the output, i.e:
[ -e * ]
will become:
[ -e Desktop Documents Downloads ... ]
Therefore trying to expand and checking in the for iteration will work.
Please see: http://mywiki.wooledge.org/WordSplitting and http://wiki.bash-hackers.org/syntax/expansion/globs

I think the case construct is too often overlooked.
case *.jpg in *.jpg ) echo found files ;; * ) echo no files found ;; esac
produces the correct message in my dir with 1000s+ jpgs ;-)
Change both references from jpg to zip and see if it works for you.
IHTH

Related

Shell: Check If File Exists When Changing Format

I'm trying to write a script that, when run, renames all .htm files in the directory to .html for a server. NO PROBLEM!
for file in *.htm ; do mv $file `echo $file | sed 's/\(.*\.\)htm/\1html/'` ; done
However, if there is a .html equivalent of a file already, it should print out "$file.html already converted - contacted administrator" and exit with status 1
I've tried using -mv and exists, but no cigar. Any help appreciated.
You should first check for the file, then try to rename it by moving.
Something like this should suffice:
for file in *.htm; do
[ -f "${file%.*}.html" ] && mv "${file}" "${file%.*}.html" || printf "%s.html already converted - contacted administrator" "${file%.*}"
done
Note that also without any substitution you can just do mv "${file}" "${file}l".
Note that if do not use an amministrative user it is safer using an if-then-else as follows:
for file in *.htm; do
if [ -f "${file%.*}.html" ]; then
mv "${file}" "${file%.*}.html"
else
printf "%s.html already converted - contacted administrator" "${file%.*}"
fi
done

Treating space as newline character in bash

I have written a bash just to display the name of all the files of a given directory but when I am running this it breaking the file name which has spaces.
if [ $# -eq 0 ]
then
echo "give a source directory in the command line argument in order to rename the jpg file"
exit 1
fi
if [ ! -d "$1" ]; then
exit 2
fi
if [ -d "$1" ]
then
for i in $(ls "$1")
do
echo "$i"
done
fi
I am getting the following thing when I run the bash script
21151991jatinkhurana_image
(co
py).jpg
24041991jatinkhurana_im
age.jpg
35041991jatinkhurana_image
.jpg
The thing that i have tried till now is resetting the IFS variable like IFS=$(echo -en "\t\n\0") but found no change....
If anyone know please help me.....
Do not loop through the result of ls. Parsing ls makes world worse (good read: Why you shouldn't parse the output of ls).
Instead, you can do make use of the *, that expands to the existing content in a given directory:
for file in /your/dir/*
do
echo "this is my file: $file"
done
Using variables:
for file in $dir/*
do
echo "this is my file: $file"
done

Bash: Creating subdirectories reading from a file

I have a file that contains some keywords and I intend to create subdirectories into the same directory of the same keyword using a bash script. Here is the code I am using but it doesn't seem to be working.
I don't know where I have gone wrong. Help me out
for i in `cat file.txt`
do
# if [[ ! -e $path/$i ]]; then
echo "creating" $i "directory"
mkdir $path/$i
# fi
grep $i file >> $path/$i/output.txt
done
echo "created the files in "$path/$TEMP/output.txt
You've gone wrong here, and you've gone wrong here.
while read i
do
echo "Creating $i directory"
mkdir "$path/$i"
grep "$i" file >> "$path/$i"/output.txt
done < file.txt
echo "created the files in $path/$TEMP/output.txt"
78mkdir will refuse to create a directory, if parts of it do not exist.
e.g. if there is no /foo/bar directory, then mkdir /foo/bar/baz will fail.
you can relax this a bit by using the -p flag, which will create parent directories if necessary (in the example, it might create /foo and /foo/bar).
you should also use quotes, in case your paths contain blanks.
mkdir -p "${path}/${i}"
finally, make sure that you are actually allowed to create directories in $path

Shell Script to add extension on file and directory

I need help to write a script that will receive arguments that are directories in the current directory and browse that directory.
If found, and it's a and directory the script adds the following extension: .aaa
But if it found a file that is pdf, or zip or mp3, it should add the following extension: .bbb
We suppose that the files do not have any extension yet
Example:
if it found the directory hello it should remane it as hello.aaa and if it find a pdf file name myfile it remanes it as myfile.pdf,
Am not sure if should use case ... in or something else:
#!/bin/sh
for dir in "$#"; do
for file in "$dir"/*;
do
if [[ -d $file ]]
then
ext=dir
else
file *
if ???????? then ext=pdf; # am not sure how to set the condition so that if teh file found is pdf to add the extension PDF.
else
if ???????? ext=zip # same thing if teh file found is zip
else
if ?????? ext=mp3 # samething if the file found is mp3
done
done
#!/bin/sh
for dir in "$#"; do
for file in "$dir"/*; do
# protect against empty dirs - the shell just passes a
# literal asterisk along in this case
case $file in
"$dir/*")
continue
;;
esac
if [ -d "$file" ]; then
ext=aaa
continue
fi
case $(file "$file") in
"gzip compressed"*)
ext=gzip
;;
"whatever file(1) says for PDFs")
ext=pdf
;;
"MP3"*)
ext=mp3
;;
# et cetera
esac
done
done

Recursively copying a file into multiple directories, if a directory does not exist in Bash

so I need to copy the file /home/servers/template/craftbukkit.jar into every folder inside of /home/servers, Ex. /home/servers/server1, /home/servers/server2, etc.
But I only want to do it if /home/servers/whateverserveritiscurrentlyon/mods does not exsist. This is what I came up with and was wondering if it will work:
echo " Script to copy a file to all server directories, only if mods does not exist in that directory"
for i in /home/servers/*/; do
if [ ! -d "$i/mods" ]; then
cp -f /home/servers/template/craftbukkit.jar "$i"
fi
done
echo " completed script ..."
Looks like it should work. To non-destructively test, change the cp -f ... line to say echo cp -f ... and review the output.
It could also be somewhat shortened, but it wouldn't affect efficiency much:
for i in /home/servers/*/
do
[[ -d "${i}/mods" ]] || cp -f /home/servers/template/craftbukkit.jar "${i}/."
done

Resources