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 |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
 |
|
09-12-2014, 11:27 AM
|
#1
|
Member
Registered: Aug 2007
Location: Melbourne
Posts: 111
Rep:
|
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.
|
|
|
09-12-2014, 12:28 PM
|
#2
|
Member
Registered: Oct 2012
Distribution: OpenSuSE,RHEL,Fedora,OpenBSD
Posts: 982
|
Code:
for i in *.JPG *.jpg *.JPEG *.jpeg
do
[ -f $i ] && do_thing_here_with $i
done
|
|
|
09-12-2014, 12:54 PM
|
#3
|
LQ Guru
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,326
|
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
...
|
|
|
09-12-2014, 02:11 PM
|
#4
|
Member
Registered: Aug 2007
Location: Melbourne
Posts: 111
Original Poster
Rep:
|
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 ?
|
|
|
09-12-2014, 04:04 PM
|
#5
|
LQ Guru
Registered: Mar 2004
Distribution: Slackware
Posts: 6,795
|
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)
|
|
|
09-12-2014, 09:06 PM
|
#6
|
Member
Registered: Aug 2007
Location: Melbourne
Posts: 111
Original Poster
Rep:
|
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.
|
|
|
09-12-2014, 10:21 PM
|
#7
|
LQ Guru
Registered: Mar 2004
Distribution: Slackware
Posts: 6,795
|
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 10:22 PM.
|
|
|
09-12-2014, 11:17 PM
|
#8
|
Member
Registered: Aug 2007
Location: Melbourne
Posts: 111
Original Poster
Rep:
|
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?
|
|
|
09-13-2014, 05:56 AM
|
#9
|
LQ Guru
Registered: Mar 2004
Distribution: Slackware
Posts: 6,795
|
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.
|
09-13-2014, 07:56 AM
|
#10
|
Member
Registered: Aug 2007
Location: Melbourne
Posts: 111
Original Poster
Rep:
|
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?
|
|
|
09-13-2014, 11:23 AM
|
#11
|
LQ Guru
Registered: Mar 2004
Distribution: Slackware
Posts: 6,795
|
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 11:30 AM.
|
|
2 members found this post helpful.
|
09-13-2014, 12:12 PM
|
#12
|
LQ Guru
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,326
|
Quote:
Originally Posted by schneidz
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 02:47 PM.
|
|
|
09-13-2014, 08:59 PM
|
#13
|
Member
Registered: Aug 2007
Location: Melbourne
Posts: 111
Original Poster
Rep:
|
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 !
|
|
|
09-13-2014, 09:14 PM
|
#14
|
Member
Registered: Aug 2007
Location: Melbourne
Posts: 111
Original Poster
Rep:
|
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.
|
|
|
09-13-2014, 10:59 PM
|
#15
|
LQ Guru
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,326
|
Quote:
Originally Posted by nyloc
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 ?
|
|
|
All times are GMT -5. The time now is 05:28 PM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|