LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices

Reply
 
Search this Thread
Old 12-28-2008, 05:52 AM   #1
alekone
LQ Newbie
 
Registered: Dec 2008
Posts: 7

Rep: Reputation: 0
bash: renaming file extension based on actual file type


hello!
I have some thousands image files with extensions messed up (ie: eps file with .tif extension).

I'm trying to determine the actual content of a file with the file command. that's what I get with the command "file *":
160076_PEZZOLI-77550.TIF: TIFF image data, big-endian
160717_caravFIG50.TIF: PostScript document text conforming at level 3.0 - type EPS
16272_BIETO02.TIF: PostScript document text conforming at level 3.0 - type EPS

I'd like to rename the EPS file with .eps extension.
I don't know how to pipe the "file" command into a grep command to replace the first extension with the correct one.
I mean, if I write "file * | grep EPS" it correctly returns all the tif that are really EPS, but how do I pipe in the filename to rename it with a regular expression?

thank you very much.
 
Old 12-28-2008, 06:44 AM   #2
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Arch/XFCE
Posts: 17,802

Rep: Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728
Welcome to LQ!!

First, GREP does not do renaming or replacement--it is strictly a filter

Second, you do not rename using a pipe. You have to use something like "mv oldname newname", where newname includes a variable containing the desired extension.
Example: rename files with the oldname (minus the old extension) in a variable "old", and the desired extension in a variable "ext":
mv $old $old$ext

Here is a generic way to go: (NOT TESTED!!)


Code:
for old in `ls|sed 's/\....$//'`; do    ##loop thru the current directory, removing all instances of "." + any 3 chars at the end of the filename.  (Note--fragile.  Only removes 3-character extensions)
   ext=`file $old|sed 's/.*\(...\)/\1/'`  ##get the filetype using file command---filetype assumed to be the last 3 chars of the output of file.  Assign to the variable "ext"
   mv $old $old.$ext  ##rename from the name in "old" to the name in "old". name in "ext"
done   ##end of loop
Note the backtics in two places (not the same as a single quote).
 
Old 12-28-2008, 07:02 AM   #3
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948
Here's a simple script I whipped up. It uses if statements to test the output of "file", then renames any matches on TIFF or EPS. It only runs through the files in the current directory.

It could probably be a whole lot better, but it seems to work for me (I didn't test it fully though). You might want to beware of any false positives. If you only want to match one type of file, just remove the unwanted if statement.

Code:
#!/bin/bash

for NAME in $(ls $PWD); do

if [ "$(file $NAME|grep EPS)" ]; then

echo "Renaming ${NAME} to ${NAME%.*}.eps"
mv ${NAME} ${NAME%.*}.eps

elif [ "$(file $NAME|grep TIFF)" ]; then

echo "Renaming ${NAME} to ${NAME%.*}.tif"
mv ${NAME} ${NAME%.*}.tif

fi

done
 
Old 12-28-2008, 07:16 AM   #4
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,414

Rep: Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966
Code:
for i in *
do
  ( file $i | grep EPS ) && mv $i $(echo $i | sed s/tif$/eps$/)
done
 
Old 12-28-2008, 07:22 AM   #5
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,414

Rep: Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966
me too slow. that's what you get for changing nappies whilst writing posts.

David's is the best there, even if his for loop input is over complex hand and if statements are quite long. bash level substitution is nicer than my spitting things through sed, but i can never remember the syntax.

and backticks are obsolete in preference to $( blah ) for reasons of clarity among others.
 
Old 12-28-2008, 07:49 AM   #6
alekone
LQ Newbie
 
Registered: Dec 2008
Posts: 7

Original Poster
Rep: Reputation: 0
thank you very much!
I'll test the second solution that seems easier to me and I'll let you know if it works!
 
Old 12-28-2008, 08:06 AM   #7
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948
Quote:
Originally Posted by acid_kewpie View Post
David's is the best there, even if his for loop input is over complex hand and if statements are quite long. bash level substitution is nicer than my spitting things through sed, but i can never remember the syntax.
Thank you. But I'm really just an amateur hacking around. I was knew when I wrote it that there must be better ways to go about it. I just went with the first thing I got working.

I do love the parameter substitution though. I've just recently discovered it, and it's really convenient and not that hard to understand. The Advanced Bash-Scripting Guide has a reference page for them here, and a longer description here.

BTW, thank you for your example. It was quite educational for me. It looks like I should look more into parentheses grouping myself.

Last edited by David the H.; 12-28-2008 at 08:19 AM.
 
Old 12-28-2008, 08:34 AM   #8
alekone
LQ Newbie
 
Registered: Dec 2008
Posts: 7

Original Poster
Rep: Reputation: 0
it works perfectly!
should I add quotes " somewhere for compatibility with filenames with spaces in them?
thank you
ale.
 
Old 12-28-2008, 09:02 AM   #9
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948Reputation: 1948
Probably the easiest way to handle files with spaces (other than renaming the files so they don't have spaces, that is ), is to temporarily change the IFS (internal field separator) shell variable so that it doesn't recognize spaces as separators.

I've been playing around and I've rewritten my script above to use a case statement instead of if. This makes it more readable and avoids having to call on grep. I've also added code to change the IFS for you. Notice that the temporary IFS value is a carriage return, which is why the end quotes are on the next line.

Code:
#!/bin/bash

OLDIFS=$IFS
IFS="
"

for NAME in $(ls $PWD); do

        case $(file $NAME) in

                *EPS* ) mv $NAME ${NAME%.*}.eps ;;

                *TIFF* ) mv $NAME ${NAME%.*}.tif ;;

                * ) echo "file $NAME not changed." ;;

        esac

done

IFS=$OLDIFS

exit 0

Last edited by David the H.; 12-28-2008 at 09:04 AM.
 
Old 12-28-2008, 09:12 AM   #10
alekone
LQ Newbie
 
Registered: Dec 2008
Posts: 7

Original Poster
Rep: Reputation: 0
wow!
that's a really interesting solution.
thank you
 
  


Reply

Tags
bash, batch, file, rename


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 On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
command to know the file extension type shivanrathore Linux - Newbie 11 06-16-2008 01:39 PM
Get file icon from extension, file type, or mime-type Guitarist88 Programming 3 04-21-2008 10:58 AM
Bash - Mass file renaming problem smudge|lala Linux - Software 2 02-14-2007 06:02 PM
Bash remove part of a file based on contents of another file bhepdogg Programming 4 01-31-2007 03:13 PM
bash help, renaming file extensions trey85stang Linux - General 8 07-21-2005 04:51 PM


All times are GMT -5. The time now is 06:20 AM.

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration