Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Rename files but not extensions?
View unanswered posts
View posts from last 24 hours
View posts from last 7 days

Goto page 1, 2  Next  
Reply to topic    Gentoo Forums Forum Index Desktop Environments
View previous topic :: View next topic  
Author Message
FizzyWidget
Veteran
Veteran


Joined: 21 Nov 2008
Posts: 1133
Location: 127.0.0.1

PostPosted: Wed Jan 25, 2012 8:45 am    Post subject: Rename files but not extensions? Reply with quote

Seeing as I am moving from Windows to Linux, I am trying to remove the spaces and . I have put into filenames and folders, is there a way using bash to change the spaces and .'s to _ but leaving the extensions of the files untouched?

eg

some folder name - some.folder.name = some_folder_name or Some_Folder_Name

some file name.jpg - some.file.name.jpg = some_file_name.jpg
_________________
I know 43 ways to kill with a SKITTLE, so taste my rainbow bitch.
Back to top
View user's profile Send private message
Bones McCracker
Veteran
Veteran


Joined: 14 Mar 2006
Posts: 1611
Location: U.S.A.

PostPosted: Wed Jan 25, 2012 11:00 am    Post subject: Reply with quote

Yes.
_________________
patrix_neo wrote:
The human thought: I cannot win.
The ratbrain in me : I can only go forward and that's it.
Back to top
View user's profile Send private message
Naib
Watchman
Watchman


Joined: 21 May 2004
Posts: 6051
Location: Removed by Neddy

PostPosted: Wed Jan 25, 2012 11:06 am    Post subject: Reply with quote

for f in *; do mv "$f" $(echo $f | tr ' ' '_'); done
_________________
Quote:
Removed by Chiitoo
Back to top
View user's profile Send private message
FizzyWidget
Veteran
Veteran


Joined: 21 Nov 2008
Posts: 1133
Location: 127.0.0.1

PostPosted: Wed Jan 25, 2012 11:07 am    Post subject: Reply with quote

Thanks naib :)

guessing for .'s i would change it to

for f in *; do mv "$f" $(echo $f | tr '.' '_'); done

?
_________________
I know 43 ways to kill with a SKITTLE, so taste my rainbow bitch.
Back to top
View user's profile Send private message
Naib
Watchman
Watchman


Joined: 21 May 2004
Posts: 6051
Location: Removed by Neddy

PostPosted: Wed Jan 25, 2012 11:10 am    Post subject: Reply with quote

yup, but that could mangle any extension as well. you can make it perserve extesion via a small tweak
_________________
Quote:
Removed by Chiitoo
Back to top
View user's profile Send private message
FizzyWidget
Veteran
Veteran


Joined: 21 Nov 2008
Posts: 1133
Location: 127.0.0.1

PostPosted: Wed Jan 25, 2012 11:11 am    Post subject: Reply with quote

i dont know how to script, only been on linux full time 3 days so far, how would i tweak it to leave extension alone?
_________________
I know 43 ways to kill with a SKITTLE, so taste my rainbow bitch.
Back to top
View user's profile Send private message
frostschutz
Advocate
Advocate


Joined: 22 Feb 2005
Posts: 2977
Location: Germany

PostPosted: Wed Jan 25, 2012 11:22 am    Post subject: Re: Rename files but not extensions? Reply with quote

Dark Foo wrote:
Seeing as I am moving from Windows to Linux, I am trying to remove the spaces and .


I don't get it. Linux can handle spaces and dots fine. Why do you want to mangle your filenames?
Back to top
View user's profile Send private message
Bones McCracker
Veteran
Veteran


Joined: 14 Mar 2006
Posts: 1611
Location: U.S.A.

PostPosted: Wed Jan 25, 2012 11:27 am    Post subject: Reply with quote

Something like this:
Code:
for file in *; do

    base=${file%.*}      #isolate filename base
    ext=${file##*.}       #preserve filename extension

    base=${base/ /_}    #convert spaces to underscore
    base=${base/./_}    #convert dot to underscore

    mv $file $base$ext   #rename the file

done

_________________
patrix_neo wrote:
The human thought: I cannot win.
The ratbrain in me : I can only go forward and that's it.


Last edited by Bones McCracker on Wed Jan 25, 2012 11:29 am; edited 1 time in total
Back to top
View user's profile Send private message
John R. Graham
Administrator
Administrator


Joined: 08 Mar 2005
Posts: 10590
Location: Somewhere over Atlanta, Georgia

PostPosted: Wed Jan 25, 2012 11:30 am    Post subject: Reply with quote

BoneKracker wrote:
Something like this...
So many quoting errors, so little time. :roll:

- John
_________________
I can confirm that I have received between 0 and 499 National Security Letters.
Back to top
View user's profile Send private message
Bones McCracker
Veteran
Veteran


Joined: 14 Mar 2006
Posts: 1611
Location: U.S.A.

PostPosted: Wed Jan 25, 2012 11:41 am    Post subject: Reply with quote

John R. Graham wrote:
BoneKracker wrote:
Something like this...
So many quoting errors, so little time. :roll:

- John

I said "something like". I'm not at my linux machine at the moment.
Are they in fact errors (in bash), or just you being obsessive-compulsive? :P
_________________
patrix_neo wrote:
The human thought: I cannot win.
The ratbrain in me : I can only go forward and that's it.
Back to top
View user's profile Send private message
John R. Graham
Administrator
Administrator


Joined: 08 Mar 2005
Posts: 10590
Location: Somewhere over Atlanta, Georgia

PostPosted: Wed Jan 25, 2012 11:55 am    Post subject: Reply with quote

Not bash syntax errors but errors nonetheless. Properly handling file names with spaces in them requires careful attention to quoting.

Now, that obsessive-compulsive question is a whole different issue. :wink:

- John
_________________
I can confirm that I have received between 0 and 499 National Security Letters.
Back to top
View user's profile Send private message
Bones McCracker
Veteran
Veteran


Joined: 14 Mar 2006
Posts: 1611
Location: U.S.A.

PostPosted: Wed Jan 25, 2012 12:10 pm    Post subject: Reply with quote

John R. Graham wrote:
Not bash syntax errors but errors nonetheless. Properly handling file names with spaces in them requires careful attention to quoting. :wink:

- John

I don' tthink there are any quoting errors. I think the string substitution won't work, because it will only replace the first character of each type (space or dot).
_________________
patrix_neo wrote:
The human thought: I cannot win.
The ratbrain in me : I can only go forward and that's it.


Last edited by Bones McCracker on Wed Jan 25, 2012 12:27 pm; edited 1 time in total
Back to top
View user's profile Send private message
Naib
Watchman
Watchman


Joined: 21 May 2004
Posts: 6051
Location: Removed by Neddy

PostPosted: Wed Jan 25, 2012 12:25 pm    Post subject: Reply with quote

well I wouldn't have named a variable "file" this is a bash command.
so for f in *

Also you are missing recreating the extension "." you changed all . to _ so it would have been: "test one.two.txt" ==> "test_one_two_txt"

The main concern would have been quotes around any variable expansion

Code:

for f in *; do
    mv "$f" "$(echo ${f%.*} | tr ". " "_").${f##*.} "
done

_________________
Quote:
Removed by Chiitoo


Last edited by Naib on Wed Jan 25, 2012 12:34 pm; edited 1 time in total
Back to top
View user's profile Send private message
Bones McCracker
Veteran
Veteran


Joined: 14 Mar 2006
Posts: 1611
Location: U.S.A.

PostPosted: Wed Jan 25, 2012 12:33 pm    Post subject: Reply with quote

Naib wrote:
well I wouldn't have named a variable "file" this is a bash command.

so for f in *

The main concern would have been quotes around any variable expansion

Code:

for f in *; do

    base="${f%.*}"      #isolate filename base
    ext="${f##*.} "      #preserve filename extension

    base="${base/ /_}"    #convert spaces to underscore
    base="${base/./_}"    #convert dot to underscore

    mv "$f" "$base$ext"   #rename the file

done

I use file as a variable name frequently, but you're probably right. I probably shouldn't use base either.

Also, as I said above, the character substitution wont' work; it will only convert the first occurrence. It should be (note double slashes in pattern):
Code:
for f in *; do

    b=${f%.*}
    e=${f##*.}

    b=${b// /_}
    b=${b//./_}

    echo $b.$e               

done

_________________
patrix_neo wrote:
The human thought: I cannot win.
The ratbrain in me : I can only go forward and that's it.


Last edited by Bones McCracker on Wed Jan 25, 2012 12:35 pm; edited 1 time in total
Back to top
View user's profile Send private message
Naib
Watchman
Watchman


Joined: 21 May 2004
Posts: 6051
Location: Removed by Neddy

PostPosted: Wed Jan 25, 2012 12:34 pm    Post subject: Reply with quote

ninja edit with a more compact solution plus an additional error in your "pseudocode" ;)
_________________
Quote:
Removed by Chiitoo
Back to top
View user's profile Send private message
Bones McCracker
Veteran
Veteran


Joined: 14 Mar 2006
Posts: 1611
Location: U.S.A.

PostPosted: Wed Jan 25, 2012 12:36 pm    Post subject: Reply with quote

Naib wrote:
ninja edit with a more compact solution plus an additional error in your "pseudocode" ;)

No, it's not simply a "more compact solution". You missed the primary change. It will no longer only change the first character; it will change them all.

I changed the filenames out of respect for your suggestion.

If the error you were talking about was the lack of a dot in the final filename, before the extension, I fixed that.

Edit: oh, and the final line should be changed back from 'echo' to 'mv $f', after testing.
_________________
patrix_neo wrote:
The human thought: I cannot win.
The ratbrain in me : I can only go forward and that's it.


Last edited by Bones McCracker on Wed Jan 25, 2012 12:38 pm; edited 1 time in total
Back to top
View user's profile Send private message
Naib
Watchman
Watchman


Joined: 21 May 2004
Posts: 6051
Location: Removed by Neddy

PostPosted: Wed Jan 25, 2012 12:38 pm    Post subject: Reply with quote

wait what? my solution is compact oO and yes it will change all occurrences since that is required (yes you pseudo wouldn't have)
all . and " " changed to "_" with file extension preservation in 1 line

Code:
for f in *; do  mv "$f" "$(echo ${f%.*} | tr ". " "_").${f##*.}"; done

_________________
Quote:
Removed by Chiitoo
Back to top
View user's profile Send private message
Bones McCracker
Veteran
Veteran


Joined: 14 Mar 2006
Posts: 1611
Location: U.S.A.

PostPosted: Wed Jan 25, 2012 12:42 pm    Post subject: Reply with quote

Naib wrote:
wait what? my solution is compact oO
all . and " " changed to "_" with file extension preservation in 1 line

Code:
for f in *; do  mv "$f" "$(echo ${f%.*} | tr ". " "_").${f##*.}"; done

:lol:

Nice and readable too. :P

He said he wanted to do it in bash. Calling tr is almost like calling sed (it's like two thirds the size of it).
_________________
patrix_neo wrote:
The human thought: I cannot win.
The ratbrain in me : I can only go forward and that's it.
Back to top
View user's profile Send private message
Naib
Watchman
Watchman


Joined: 21 May 2004
Posts: 6051
Location: Removed by Neddy

PostPosted: Wed Jan 25, 2012 12:47 pm    Post subject: Reply with quote

well tr is part of coreutils

but in pure bash, you // for all replace would do:


Code:
for f in *; do  t="${f// /_}"; mv "$f" "${t//./_}.${f##*.}"; done

_________________
Quote:
Removed by Chiitoo
Back to top
View user's profile Send private message
Bones McCracker
Veteran
Veteran


Joined: 14 Mar 2006
Posts: 1611
Location: U.S.A.

PostPosted: Wed Jan 25, 2012 12:51 pm    Post subject: Reply with quote

Naib wrote:
wait what? my solution is compact oO and yes it will change all occurrences since that is required (yes you pseudo wouldn't have)
all . and " " changed to "_" with file extension preservation in 1 line

Code:
for f in *; do  mv "$f" "$(echo ${f%.*} | tr ". " "_").${f##*.}"; done

No, my solution works (changes all occurrences), and it's entirely in bash, and it's readable.
Code:
for f in *; do

    b=${f%.*}
    e=${f##*.}

    b=${b// /_}
    b=${b//./_}

    mv $f $b.$e               

done

Also, echoing to a pipe is a sure sign of an amateur. If you're echoing to a pipe, you're doing something wrong. :P
_________________
patrix_neo wrote:
The human thought: I cannot win.
The ratbrain in me : I can only go forward and that's it.
Back to top
View user's profile Send private message
John R. Graham
Administrator
Administrator


Joined: 08 Mar 2005
Posts: 10590
Location: Somewhere over Atlanta, Georgia

PostPosted: Wed Jan 25, 2012 12:59 pm    Post subject: Reply with quote

I stand corrected on the quoting. Didn't know that a variable expansion was treated atomically. However,
Code:
~ $ f="b.c.d.e"
~ $ e=${f##.*}
~ $ echo $e
b.c.d.e
- John
_________________
I can confirm that I have received between 0 and 499 National Security Letters.
Back to top
View user's profile Send private message
Naib
Watchman
Watchman


Joined: 21 May 2004
Posts: 6051
Location: Removed by Neddy

PostPosted: Wed Jan 25, 2012 1:04 pm    Post subject: Reply with quote

BoneKracker wrote:
Naib wrote:
wait what? my solution is compact oO and yes it will change all occurrences since that is required (yes you pseudo wouldn't have)
all . and " " changed to "_" with file extension preservation in 1 line

Code:
for f in *; do  mv "$f" "$(echo ${f%.*} | tr ". " "_").${f##*.}"; done

No, my solution works (changes all occurrences), and it's entirely in bash, and it's readable.
Code:
for f in *; do

    b=${f%.*}
    e=${f##*.}

    b=${b// /_}
    b=${b//./_}

    mv $f $b.$e               

done

Also, echoing to a pipe is a sure sign of an amateur. If you're echoing to a pipe, you're doing something wrong. :P

one could also say liberal use of temporary variables or over reuse to cascade formatting is also a sign of an amateur, read my last on ;)
Code:
for f in *; do  t="${f// /_}"; mv "$f" "${t//./_}.${f##*.}"; done

pure bash, 1 temp, no re-assignment, no pipes
_________________
Quote:
Removed by Chiitoo
Back to top
View user's profile Send private message
Bones McCracker
Veteran
Veteran


Joined: 14 Mar 2006
Posts: 1611
Location: U.S.A.

PostPosted: Wed Jan 25, 2012 1:08 pm    Post subject: Reply with quote

Naib wrote:
BoneKracker wrote:
Naib wrote:
wait what? my solution is compact oO and yes it will change all occurrences since that is required (yes you pseudo wouldn't have)
all . and " " changed to "_" with file extension preservation in 1 line

Code:
for f in *; do  mv "$f" "$(echo ${f%.*} | tr ". " "_").${f##*.}"; done

No, my solution works (changes all occurrences), and it's entirely in bash, and it's readable.
Code:
for f in *; do

    b=${f%.*}
    e=${f##*.}

    b=${b// /_}
    b=${b//./_}

    mv $f $b.$e               

done

Also, echoing to a pipe is a sure sign of an amateur. If you're echoing to a pipe, you're doing something wrong. :P

one could also say liberal use of temporary variables or over reuse to cascade formatting is also a sign of an amateur, read my last on ;)
Code:
for f in *; do  t="${f// /_}"; mv "$f" "${t//./_}.${f##*.}"; done

pure bash, 1 temp, no re-assignment, no pipes

All you did what take mine and compress it to unreadability. But that conciseness would be desirable if somebody was trying to use 'find' to do this (like if the files were scattered all over the disk) with an -exec and shell command.
_________________
patrix_neo wrote:
The human thought: I cannot win.
The ratbrain in me : I can only go forward and that's it.
Back to top
View user's profile Send private message
FizzyWidget
Veteran
Veteran


Joined: 21 Nov 2008
Posts: 1133
Location: 127.0.0.1

PostPosted: Wed Jan 25, 2012 2:20 pm    Post subject: Reply with quote

Yes i will be using bash, is there another shell that i should be using? Only using that one because i followed the handbook, which ever is suggested i can use :)
_________________
I know 43 ways to kill with a SKITTLE, so taste my rainbow bitch.
Back to top
View user's profile Send private message
RazielFMX
l33t
l33t


Joined: 23 Apr 2005
Posts: 835
Location: NY, USA

PostPosted: Wed Jan 25, 2012 2:43 pm    Post subject: Reply with quote

1) Copy and paste the following into a file, say ~/stripSpaces.pl

Code:
#!/usr/bin/perl -w

use strict;
use Cwd qw(getcwd);
use File::Copy qw(move);

my $dir = getcwd();

opendir(DIR, $dir) or die $!;

my $exitCode = 0;
while (my $file = readdir(DIR)) {
    next if ($file !~ /\s+/o); # Don't bother with things that lack spaces

    my $new;

    if ($file =~ /^(.+)\.(\S+)$/o) {
        my $base = $1;
        my $ext = $2;
       
        $base =~ s/\s/_/go;
        $new = join('.', $base, $ext);
    } else {
        ($new = $file) =~ s/\s/_/go;
    }
   
    print STDERR "[INFO] Renaming '$file' to '$new'\n";
   
    my $check = move($file, $new);
    if (! $check) {
        print STDERR "[WARN] Unable to rename '$file' to '$new': $!\n";
        # File::Copy::Move can leave artifacts on the FS
        if (-e $new) {
            unlink $new;
        }
       
        $exitCode = -1 if ($exitCode == 0);
    }
}

closedir(DIR);

exit($exitCode);


2) chmod it: chmod 755 ~/stripSpaces.pl

3) Run it in the directory you want to.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Desktop Environments All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum