Tell me more ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

How can be done coping files that have some suffix at the end, into same dir with the smallest command possible:

Example have directory containing files:

  • cassandra.yml.example
  • database.yml.example
  • facebook.yml.example
  • cache.yml.example
  • system.yml.example

need to copy them and have names like this:

  • cassandra.yml
  • database.yml
  • facebook.yml
  • cache.yml
  • system.yml
share|improve this question
I`ve figured about such thing: for x in ./config/*.example; do cp $x ./config/basename $x .example; done – Vitaliy Yanchuk Dec 7 '12 at 12:12
2  
you can even get rid of the basename call (at least with recent-enough bash): for x in ./config/*.example; do n=${x##*/}; cp $x dest/dir/${n%.example}; done – peterph Dec 7 '12 at 12:59
If you use zsh, zmv '(*).example' '$1' – Kevin Dec 8 '12 at 0:22

3 Answers

for x in /path/to/*.example
do
  cp "$x" "${x%%.example}"
done

Will make a copy without the .example into the same folder as the source file.

share|improve this answer
This doesn't work with files with spaces – laebshade Dec 9 '12 at 21:53
If the variables are inclosed in double quotes the spaces should be perserved. – llua Dec 11 '12 at 3:25

Requires find and a shell that supports string manipulation and process substitution (i.e. Bash and any compatible):

while read file
    do cp $file ${file%%.ext}
done < <(find -type f)

If you want to copy all files without extensions, you can use the glob (*) instead of ext.

share|improve this answer

If you want to remove a specific, unchanging, suffix, do this:

for n in $(ls *.example | sed 's/.example//'); do\
   mv "$n".example "$n";\
done

This assumes that your names do not contain spaces or other weird characters (as they shouldn't), if they do, use this instead:

find . -name "*.example" | sed 's/.example//' | while IFS= read -r n; do \
   mv "$n".example "$n"; \
done

If the suffix can change, something like this should work:

find . -type f | while IFS= read -r n; do\
   perl -e '$ARGV[0]=/(.+)\..+?$/; `mv $ARGV[0] $1`' "$n";
done
share|improve this answer
1  
Do not parse the output of ls, and always put double quotes around variable substitutions. Your first and third commands mangles a lot of file names. See llua's answer for how to do it right. The second one is fixable by using while IFS= read -r n. – Gilles Dec 7 '12 at 22:27
@Gilles, the fist example uses ls because it is simpler but I warn that it won't work on file names with spaces. While I completely agree that llua's answer is more elegant, I specifically tested the 2nd and 3rd examples to make sure they don't break on spaces. At least on my BASH they work perfectly. What type of file name would the 3rd command mangle? – terdon Dec 8 '12 at 17:35
1  
Backslashes and final whitespace (and of course newlines) due to read. Also whitespace and globbing character due to the echo $n which should have been echo "$n", or better b=$(perl -e '$_ = $ARGV[0]; s/…/…/'; print' "$n") — or since you do the whole thing in Perl also make it do the renaming. – Gilles Dec 8 '12 at 17:50
@Gilles, ah backspaces and newlines, I did not think of that. Thanks for the clarification. – terdon Dec 8 '12 at 18:04

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.