Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have a directory with automatically generated files that all end with the .sample extension. I would like to have a way to remove the .sample extension from them all in one terminal command.

I tried this:

mv ./{$1}*.sample ./$1

But it doesn't work because I'm definitely placing the {$1} in the wrong place or way. Can anyone point to the right direction?

Thanks in advance.

share|improve this question
    

5 Answers 5

up vote -3 down vote accepted

One of the many way to do that:

for i in *.sample; do NEWNAME=`echo "$i" | sed 's/\.sample//'`; mv "$i" "$NEWNAME"; done
share|improve this answer
1  
basename is more appropriate; besides your code is wrong: it will croak on filenames with space –  niXar Sep 12 '09 at 17:37
    
Corrected for space problem –  radius Sep 12 '09 at 17:44
2  
This has a few other pathological problems as well. Consider what happens if a file is named '*.sample' or 'foo.sample.sample'. See Mark Drayton's solution. –  D.Shawley Sep 12 '09 at 18:10
    
It fails for file names with multiple spaces, e.g. a b.sample. You should use echo "$i" instead of echo $i. –  Cristian Ciupitu Sep 12 '09 at 19:13
    
Thanks Cristian, correted. @rogeriopvl you should probably accept markdrayton answer, so that I could suppress my not so good solution. –  radius Sep 12 '09 at 19:26
$ touch {a,b,c,"white space"}.sample

$ ls *.sample
a.sample    	c.sample
b.sample    	white space.sample

$ for SAMPLE in *.sample; do mv -v "$SAMPLE" "${SAMPLE%.sample}"; done
a.sample -> a
b.sample -> b
c.sample -> c
white space.sample -> white space

Edit: Also see ${parameter#word}, which deletes word from the front of parameter:

$ FILENAME=140909_stats_report.txt
$ echo "${FILENAME#140909_}"
stats_report.txt

I remember which of these I need from the positions of the # and % keys on my (UK) keyboard: # is left of % so matches on the left. Before I noticed that I had to check the man page every time :~)

These expansions also support shell wildcards:

$ echo "${FILENAME%.*}"
140909_stats_report

The # and % forms match the shortest expansion of word. You can use ## or %% for the longest match. E.g.:

$ FILENAME=140909_stats_report.txt
$ echo "${FILENAME#*_}"  # match as little as possible
stats_report.txt
$ echo "${FILENAME##*_}" # match as much as possible
report.txt

It's worth getting to grips with these expansions. There's several more, including (somewhat cranky) regex support, substrings and ways to set defaults or get variable lengths. Man bash, of course.

share|improve this answer
3  
+1 - using the bash parameter substitution is the best solution. No unnecessary processes are spawned and the result is very clean. –  D.Shawley Sep 12 '09 at 18:03
for n in *.sample ; do mv "$n" "$(basename "$n" .sample)" ; done
share|improve this answer

The rename command accepts Perl expressions:

rename 's/\.sample$//' *.sample

Example:

$ ls *sample*
file0.sample  file2.sample  foo.sample.sample
file1.sample  file3.sample  with space.sample
$ rename 's/\.sample$//' *.sample
$ ls *sample*
foo.sample

On my Ubuntu system, rename is symlinked to the prename script from the perl package.

share|improve this answer
rename '.sample' '' *.sample

On Fedora, the rename command is included in the util-linux-ng package.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.