View previous topic :: View next topic |
Author |
Message |
padukes Apprentice
Joined: 27 Feb 2003 Posts: 232
|
Posted: Fri Mar 12, 2004 1:14 pm Post subject: Shell script question |
|
|
Hi,
I have a bunch of files that look like "blah_blah_blah" that I would like to rename to "blah blah blah". I know I can write a simple script that can do a loop through a directory, find each file check it, fix it and rename it. Something like:
Code: | #!/bin/sh
IFS="
"
for i in $(find $DIR -type f -name "*_*" -print)
do
filename=$(basename $i)
fixed_name=$(echo $filename | sed 's/_/ /g')
if [ "$filename" != "$fixed_name" ]; then
mv -v "$i" "`dirname $i`/$fixed_name"
fi
done
|
But I was wonder if it were possible to do this in one line - something like:
Code: | find $DIR -type f -name "*_*" -print | xargs mv <somehow> |
Thanks,
P |
|
Back to top |
|
|
cvk Guru
Joined: 06 Jan 2003 Posts: 314 Location: Our house, in the middle of our street
|
Posted: Fri Mar 12, 2004 1:47 pm Post subject: |
|
|
Something like
Code: | find . -type f -name "*_*" -exec mv {} `echo {} | sed "s/_/ /g"` \; |
might work
Regards,
Chris _________________ Adopt an unanswered post now. |
|
Back to top |
|
|
padukes Apprentice
Joined: 27 Feb 2003 Posts: 232
|
Posted: Fri Mar 12, 2004 2:16 pm Post subject: |
|
|
Thanks a lot - that seems really close but it doesn't seem to be honoring the pipe within the find -exec call.
Here's some results I get:
Code: | phoenix root # find -name "*101*" -exec echo `echo {} | sed "s/101/999/g"` \;
./scripts/101-states.sh |
I would expect to get
Code: | ./scripts/999-states.sh |
Any suggestions?
P |
|
Back to top |
|
|
padukes Apprentice
Joined: 27 Feb 2003 Posts: 232
|
Posted: Fri Mar 12, 2004 4:04 pm Post subject: |
|
|
This might be a little clearer:
Code: | phoenix root # echo "zza" | xargs -i echo `echo pi{} | tr [a-z] [A-Z]` |
I would expect the above to produce
But for some reason the {} doesn't get piped and it produces:
Is this a bug, or am I just doing something wrong?
Thanks,
P |
|
Back to top |
|
|
Andersson Guru
Joined: 12 Jul 2003 Posts: 525 Location: Göteborg, Sweden
|
Posted: Fri Mar 12, 2004 4:30 pm Post subject: |
|
|
padukes wrote: | This might be a little clearer:
Code: | phoenix root # echo "zza" | xargs -i echo `echo pi{} | tr [a-z] [A-Z]` |
I would expect the above to produce
|
Remove the extra `echo
Code: | bash$ echo "zza" | xargs -i echo pi{} | tr [a-z] [A-Z]
PIZZA |
|
|
Back to top |
|
|
cvk Guru
Joined: 06 Jan 2003 Posts: 314 Location: Our house, in the middle of our street
|
Posted: Fri Mar 12, 2004 4:37 pm Post subject: |
|
|
Well, there seems to be something wrong with piping the {}, but this should work:
Code: | for i in `find -type f -name "*_*"`; do mv "$i" "`echo $i | tr _ \ `"; done |
Regards,
Chris _________________ Adopt an unanswered post now. |
|
Back to top |
|
|
padukes Apprentice
Joined: 27 Feb 2003 Posts: 232
|
Posted: Fri Mar 12, 2004 4:50 pm Post subject: |
|
|
Hey all,
Thanks a lot for your responses. Here're my remaining issues:
1. Andersson -
The original question had to do with moving files - so the end result would be something like Your solution pipes the entire output of xargs into tr which means I'll end up with something like and no way to find the original file "blah". Any suggestions for how to do this?
2. cvk -
Thanks for your solution - this works but (although it's slimmer) it feels much like my original script because it uses a "for" loop. I was hoping to have a one-liner that just uses existing programs without flow control.
I know this is kind of an arbitrary task - but any other suggestions?
Thanks so much for your help,
P |
|
Back to top |
|
|
teilo Apprentice
Joined: 20 Jun 2003 Posts: 276 Location: Minneapolis, MN
|
Posted: Fri Mar 12, 2004 5:28 pm Post subject: |
|
|
Have you looked at the rename command?
Code: | ACCEPT_KEYWORDS="~x86" emerge rename
man rename |
_________________ Teilo who is called Teilo |
|
Back to top |
|
|
padukes Apprentice
Joined: 27 Feb 2003 Posts: 232
|
Posted: Fri Mar 12, 2004 6:25 pm Post subject: |
|
|
Great suggestion teilo!
I did look at rename and unfortunately it only replaces the first instance of the characters it finds
For example:
will turn "blah_blah_blah" into "blah blah_blah" which is great and I could run it until all _ are replaced. Which is kind of ugly but will work!
In addition, as this thread has gone I've started to wonder why the {} in the xargs above doesn't work - Any ideas or other suggestions?
Thanks again for the help,
-P |
|
Back to top |
|
|
sapphirecat Guru
Joined: 15 Jan 2003 Posts: 376
|
Posted: Fri Mar 12, 2004 6:47 pm Post subject: |
|
|
When things get difficult in the shell I tend to fall back on perl.
Code: | perl -e 'for(@ARGV) { ($i = $_) =~ s/_/ /g; system(q{mv}, $_, $i); }' *_* |
edit: if you're using find, replace *_* with `find stuff`. _________________ Former Gentoo user; switched to Kubuntu 7.04 when I got sick of waiting on gcc. Chance of thread necro if you reply now approaching 100%... |
|
Back to top |
|
|
teilo Apprentice
Joined: 20 Jun 2003 Posts: 276 Location: Minneapolis, MN
|
Posted: Fri Mar 12, 2004 6:53 pm Post subject: |
|
|
Quote: | I did look at rename and unfortunately it only replaces the first instance of the characters it finds |
Not true. You were looking at the wrong rename command, probably the one that came with your linux-tools (or wherever it comes from).
The package is different. It supports regular expressions, which is exactly what you need.
Version 1.3, which is masked, will allow you to replace all instances in the filename. To do this, you need a regular expression:
In other words: replace all instances of "_" with " ", globally, meaning, everywhere it occurs in the filename. Give it a try. It works. _________________ Teilo who is called Teilo |
|
Back to top |
|
|
cvk Guru
Joined: 06 Jan 2003 Posts: 314 Location: Our house, in the middle of our street
|
Posted: Fri Mar 12, 2004 7:00 pm Post subject: |
|
|
Hey thanks. I was looking for something like that.
/me hands the guru medal over to teilo
Chris _________________ Adopt an unanswered post now. |
|
Back to top |
|
|
|