LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 09-12-2014, 10:27 AM   #1
nyloc
Member
 
Registered: Aug 2007
Location: Melbourne
Posts: 111

Rep: Reputation: 17
Talking extra help with bash


I've been reading a lot of tutorials but cant find exactly what I want.
I want to check if there are any JPG or jpeg files before I process them with ImageMagik.
All I have found is
if [ -f filename ]
which only checks for one file, I want to check for *.JPG but using if [ -f *.JPG ] fails if more than one JPG file exists.

Keefaz big thanks, that script for identify worked well and after changing $h > 800 to $w >= $h I got rid of the portrait orientated pics as well as the small ones. It takes 10 - 15 minutes to process approx 12500 files and I can live with that especially as my box is about 7 years old.
 
Old 09-12-2014, 11:28 AM   #2
linosaurusroot
Member
 
Registered: Oct 2012
Distribution: OpenSuSE,RHEL,Fedora,OpenBSD
Posts: 982
Blog Entries: 2

Rep: Reputation: 244Reputation: 244Reputation: 244
Code:
for i in *.JPG *.jpg *.JPEG *.jpeg
do
  [ -f $i ] && do_thing_here_with $i
done
 
Old 09-12-2014, 11:54 AM   #3
schneidz
LQ Guru
 
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,313

Rep: Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918
i would do something like this:
Code:
[schneidz@hyper ~]$ find /var/www/html/beat-la/photos/ -exec file -i '{}' \;
/var/www/html/beat-la/photos/dscf0117.jpg: image/jpeg; charset=binary
/var/www/html/beat-la/photos/dscf0138.jpg: image/jpeg; charset=binary
/var/www/html/beat-la/photos/dscf0139.jpg: image/jpeg; charset=binary
/var/www/html/beat-la/photos/dscf0118.jpg: image/jpeg; charset=binary
/var/www/html/beat-la/photos/dscf0169.jpg: image/jpeg; charset=binary
...
 
Old 09-12-2014, 01:11 PM   #4
nyloc
Member
 
Registered: Aug 2007
Location: Melbourne
Posts: 111

Original Poster
Rep: Reputation: 17
Oops I haven't explained my problem properly. I want to make all JPG and jpeg files jpg files. At the moment I do "rename JPG jpg *.JPG" (same for jpeg) and ignore the error message when there are no files to be changed. I would much prefer to have the rename in some sort of test.

Second question is to do with tidying up the file names. The script I found uses tr so I have ended up with this bit of code

image3=`echo "$image2" | tr " " "_"`
if [ "$image3" != "$image1" ]; then
mv "$image1" "$image3"
fi

But I really would like to be able to do the test first. Anyone got any alternatives ?
 
Old 09-12-2014, 03:04 PM   #5
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
I am not a sed specialist but...
Code:
image3=$(echo "$image1" | sed -e 's/ /_/g' -e 's/\(.*\)\..\{3,4\}$/\1.jpg/')

[ ! -f "$image3" ] && mv "$image1" "$image3"
(used $image1 as I don't know what $image2 is)
 
Old 09-12-2014, 08:06 PM   #6
nyloc
Member
 
Registered: Aug 2007
Location: Melbourne
Posts: 111

Original Poster
Rep: Reputation: 17
Looks like your sed knowledge is better than my typing ability (image2 should read image1). Still have the issue of doing the test after the change, which I was taught is bad programming.
If it helps you with sed while searching script tutorials I came across this
# badname.sh
# Delete filenames in current directory containing bad characters.

for filename in *
do
badname=`echo "$filename" | sed -n /[\+\{\;\"\\\=\?~\(\)\<\>\&\*\|\$]/p`
# badname=`echo "$filename" | sed -n '/[+{;"\=?~()<>&*|$]/p'` also works.
# Deletes files containing these nasties: + { ; " \ = ? ~ ( ) < > & * | $
#
echo "rm " "$badname"
# rm $badname 2>/dev/null
# ^^^^^^^^^^^ Error messages deep-sixed.
done

but that doesn't solve the issue of I would rather do the test for spaces (and/or other dodgy characters) before changing the file name.
 
Old 09-12-2014, 09:21 PM   #7
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
Test for spaces doesn't matter as long as you just manipulate the file name
After you finish the name change, you just test with -f if file exists before doing the actual rename

PS: thanks for the sed examples, have to dig it a little more

Last edited by keefaz; 09-12-2014 at 09:22 PM.
 
Old 09-12-2014, 10:17 PM   #8
nyloc
Member
 
Registered: Aug 2007
Location: Melbourne
Posts: 111

Original Poster
Rep: Reputation: 17
I could get silly and say :- but, but, but, even COBOL lets you say
IF filename INCLUDES a space THEN PERFORM the change
However I know shell scripting is not compiled and therefore is limited in what can be done.
Would it be possible to write a bash function along the lines of

Function Includes(filename)
local respone = false
move filename to an array of single characters the length of filename # this line is the tricky bit
for cnt = 1 , length of filename
do
if array[cnt] = " "
then
response = true
fi
od
return response

I can see issues with the above code already, such as it probably should return true
as soon as it finds a space. More importantly if I was to write that then it would seem
sensible to change the space characters there and return the new file name and then I wouldn't
need the line with tr in it.

ps how do stop the rename getting errors?
 
Old 09-13-2014, 04:56 AM   #9
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
You can do the space test more easily, bash has reg exp matching function

Code:
name="this is a name with spaces"

if [[ $name =~ " " ]]; then
   echo "yes I have spaces"
else
   echo "no, I haven't any space"
fi
 
2 members found this post helpful.
Old 09-13-2014, 06:56 AM   #10
nyloc
Member
 
Registered: Aug 2007
Location: Melbourne
Posts: 111

Original Poster
Rep: Reputation: 17
My other issue is I need a "move_all_but *.jpg to_somewhere_else" command. At the moment I am doing

mkdir $tmp_dir
mkdir $oth_dir
mv *.jpg $tmp_dir
mv *.* $oth_dir
mv $tmp_dir/* .
rmdir $tmp_dir

which looks really ugly to me.
Can anyone suggest a more elegant solution?
 
Old 09-13-2014, 10:23 AM   #11
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
You can use bash GLOBIGNORE env variable to ignore .jpg files, something like:

Code:
GLOBIGNORE="*.jpg" 
mv * $dir
then all files but jpgs are moved to $dir

Last edited by keefaz; 09-13-2014 at 10:30 AM.
 
2 members found this post helpful.
Old 09-13-2014, 11:12 AM   #12
schneidz
LQ Guru
 
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,313

Rep: Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918
Quote:
Originally Posted by schneidz View Post
i would do something like this:
Code:
[schneidz@hyper ~]$ find /var/www/html/beat-la/photos/ -exec file -i '{}' \;
/var/www/html/beat-la/photos/dscf0117.jpg: image/jpeg; charset=binary
/var/www/html/beat-la/photos/dscf0138.jpg: image/jpeg; charset=binary
/var/www/html/beat-la/photos/dscf0139.jpg: image/jpeg; charset=binary
/var/www/html/beat-la/photos/dscf0118.jpg: image/jpeg; charset=binary
/var/www/html/beat-la/photos/dscf0169.jpg: image/jpeg; charset=binary
...
since your filenames are inconsistent to me it makes better sense to use the mime-type (file -i) to figure out the actual file type.

this worx for me:
Code:
[schneidz@hyper jamtat]$ file /var/www/html/beat-la/photos/*
/var/www/html/beat-la/photos/dscf0102.jpg:      JPEG image data, JFIF standard 1.01
/var/www/html/beat-la/photos/dscf0133.jpg:      JPEG image data, JFIF standard 1.01
/var/www/html/beat-la/photos/dscf0143.jpg:      JPEG image data, JFIF standard 1.01
/var/www/html/beat-la/photos/hello-world.jpg:   ASCII text
/var/www/html/beat-la/photos/this is a picture: JPEG image data, JFIF standard 1.01
[schneidz@hyper jamtat]$ find /var/www/html/beat-la/photos/ -exec sh -c "file -i '{}' | grep image.*charset=binary$" \; -exec sh -c 'filename="${0##*/}"; ln -sf "$0" bak/`echo $filename | tr " " "-"`' {} \;
/var/www/html/beat-la/photos/dscf0143.jpg: image/jpeg; charset=binary
/var/www/html/beat-la/photos/this is a picture: image/jpeg; charset=binary
/var/www/html/beat-la/photos/dscf0102.jpg: image/jpeg; charset=binary
/var/www/html/beat-la/photos/dscf0133.jpg: image/jpeg; charset=binary
[schneidz@hyper jamtat]$ ll bak
total 0
lrwxrwxrwx. 1 schneidz schneidz 38 Sep 13 14:37 dscf0102.jpg -> /var/www/html/beat-la/photos/dscf0102.jpg
lrwxrwxrwx. 1 schneidz schneidz 38 Sep 13 14:37 dscf0133.jpg -> /var/www/html/beat-la/photos/dscf0133.jpg
lrwxrwxrwx. 1 schneidz schneidz 38 Sep 13 14:37 dscf0143.jpg -> /var/www/html/beat-la/photos/dscf0143.jpg
lrwxrwxrwx. 1 schneidz schneidz 43 Sep 13 14:37 this-is-a-picture -> /var/www/html/beat-la/photos/this is a picture

Last edited by schneidz; 09-13-2014 at 01:47 PM.
 
Old 09-13-2014, 07:59 PM   #13
nyloc
Member
 
Registered: Aug 2007
Location: Melbourne
Posts: 111

Original Poster
Rep: Reputation: 17
The script is getting better, processed about 30000 files in 16 minutes yesterday.
I like the idea of GLOBIGNORE.
So will have to do some more testing today.
I'm getting really really bored with two things, one - spending what seems like hours going through tutorials and not finding what I need, two Hello World !
 
Old 09-13-2014, 08:14 PM   #14
nyloc
Member
 
Registered: Aug 2007
Location: Melbourne
Posts: 111

Original Poster
Rep: Reputation: 17
Keefaz there is a slight bug in your GLOBIGNORE example. It needs mv *.* $dir otherwise it tries to move $dir into a subdirectory of itself.
 
Old 09-13-2014, 09:59 PM   #15
schneidz
LQ Guru
 
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,313

Rep: Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918
Quote:
Originally Posted by nyloc View Post
Keefaz there is a slight bug in your GLOBIGNORE example. It needs mv *.* $dir otherwise it tries to move $dir into a subdirectory of itself.
what if the dir name is dir.name ?
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LVM - creating extra logical volumes (using extra space outside LVM) rhbegin Linux - Server 1 01-30-2013 07:08 PM
Bash problem : -bash: [: /bin/bash: unary operator expected J.A.X Linux - Software 1 09-22-2011 05:52 AM
Remove extra new lines (BASH) akamikeym Programming 9 07-15-2010 10:56 AM
LXer: Fedora's Extra Packages for Enterprise Linux the Extra Mile LXer Syndicated Linux News 0 06-20-2008 10:10 PM
bash: extra stuff in brace expansion jhwilliams Programming 4 09-07-2007 02:44 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 07:53 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration