1752653 Members
5729 Online
108788 Solutions
New Discussion юеВ

extention of filename

 
SOLVED
Go to solution
MAYIANAN
Advisor

extention of filename

Hi frns,

Got stuck up with simple functionality. Just need to get the filename extention. I am not sure about the number of dots in the filename. It will be like,

filename.xls.zip
filename.xls
filename.in.xls.zip

just need to get the extention also. help me out. thx
11 REPLIES 11
James R. Ferguson
Acclaimed Contributor

Re: extention of filename

Hi:

# F=filename.in.xls.zip
# basename ${F} .zip
filename.in.xls

See the manpages for 'basename'.

Regards!

...JRF...

MAYIANAN
Advisor

Re: extention of filename

Hi James,

What you have given is for stripping out the extention .zip.

But my requirement is to get the extention, here are some of the cases,

1) filename.xls.zip
-- I need to get zip as extention in a variable

2) filename.xls
-- I need to get xls as extention in a variable.

Thanks
Mayil
Ivan Krastev
Honored Contributor
Solution

Re: extention of filename

Use awk. Here is an example:

cat test.txt
1.txt
2.txt.xls
3.zip.xls.rar


awk -F"." '{ print $NF }' < test.txt
txt
xls
rar


regards,
ivan
Hein van den Heuvel
Honored Contributor

Re: extention of filename

Check out the 'Parameter Substitution' rule for the shell.
In the man page, look for ##
man -sh-posix
/##

Assuming a file 'x' with your list:

Usage example:

$ cat x.sh
for file in $(do
ext=${file##*.}
echo --- $ext $file ---
done
$ ./x.sh
--- zip filename.xls.zip ---
--- xls filename.xls ---
--- zip filename.in.xls.zip ---

Using perl...

$ perl -lpe 's/.*\.//' x
zip
xls
zip

Cheers,
Hein.

Example of more file name matching variants.

$ cat x.sh
for file in $(do
a=${file%.*}
b=${file%%.*}
c=${file#*.}
d=${file##*.}
echo --- $file $a $b $c $d ---
done
$
$ ./x.sh
--- filename.xls.zip filename.xls filename xls.zip zip ---
--- filename.xls filename filename xls xls ---
--- filename.in.xls.zip filename.in.xls filename in.xls.zip zip ---

Rasheed Tamton
Honored Contributor

Re: extention of filename

Hi,

To make it more simple:

ll file*|awk -F\. '{print $NF}'

ll filename*|awk -F"." '{print $NF}'


-F with awk is the delimiter (here . - that is escaped with either a backslash or quotes) which splits the columns and $NF is the last field. So you do not have to worry about the number of dots.
Rasheed Tamton
Honored Contributor

Re: extention of filename

For putting in to variable:
put the commands in between the back quotes (`) the leftmost key in the normal PC keyboard (with the tilde ~).

for i in `ll file*|awk -F\. '{print $NF}'`
do
echo $i
done
zip
xls
zip
Hein van den Heuvel
Honored Contributor

Re: extention of filename

Minor comments...

Rasheed>> To make it more simple:

How is that any more simple than what Ivan already showed.


Rasheed>> put the commands in between the back quotes (`)

Hmmm, you may want to consider using $() as shown in an earlier reply here. It seems to be the way forward, and IMHO is more readable.

Also.... if you just want the file names, then why make the system pick up all attributes. That is, just use ls instead of ll for this excercise.

But really... why activate a sub-process to run ls at all? These are simple, shell-only, tasks. My earlier example assmed a list of file names as input.
If there is a directory with file as per your example, then you can use for example:

$ ls file*
filename.in.xls.zip filename.xls filename.xls.zip
$
$ for file in *(file*)
> do
> echo ${file##*.}
> done
zip
xls
zip

fwiw,
Hein.

MAYIANAN
Advisor

Re: extention of filename

found the solution from the reply
Dennis Handly
Acclaimed Contributor

Re: extention of filename

>Rasheed: -F with awk is the delimiter (here . - that is escaped with either a backslash or quotes)

Hmm, this works, but it completely unexpected, if you read the documentation closely.
awk(1) says that -F is a regular expression. And later it implies it only does extended regular expressions. And a "." is special. So you should have to use:
-F'\.'

There was another thread using "||" and both had to be quoted but a single one doesn't???
http://forums.itrc.hp.com/service/forums/questionanswer.do?threadId=1253990

So this seems to imply that if -F or FS only has one char, it stands for itself. ???

>Hein: for file in *(file*); do

Any reason you used composite patterns rather than the obvious:
for file in file*; do

You aren't getting the zero or more part.
I.e. there must be some other rule that says that if there are no other matches, then that zero matches isn't selected.