LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 11-15-2012, 06:23 PM   #1
alaw005
LQ Newbie
 
Registered: Jul 2010
Posts: 2

Rep: Reputation: 0
How to shorten file name recursively using grep and rename


Hi, I have spent hours trying to solve what I thought was a simple problem. I have a large number of file names that are too long in a number of folders.

I am trying to shorten the length of each file name using:

Code:
find . -name '*' -print0 | xargs -0 rename -n 's/^(.*\/?).(.{25})(\..*)$/$1$2$3/' *
The regex doesn't work, The first part of the regex is supposed to keep the file path, the second part is supposed to truncate the file name to 25 characters and the last part of supposed to keep the extension but its just not working. I have tried to find answer by searching internet (for almost 3 hours!) to no avail.

NB: The path and file name may have spaces in them. Also, I am using the "rename -n" flag to ensure no changes made while testing. And I'm on ubuntu.

Please help save my sanity.
 
Old 11-15-2012, 09:38 PM   #2
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Arch/XFCE
Posts: 17,802

Rep: Reputation: 738Reputation: 738Reputation: 738Reputation: 738Reputation: 738Reputation: 738Reputation: 738
I can't find any reference to a Linux "rename" command with that syntax---can you provide a link?

Assuming that the syntax is legal, it looks like the SED "s" command. But--using SED rules--I see a bunch of problems.

Finally, I wonder about using find when you are accepting any and all results.
 
Old 11-15-2012, 09:58 PM   #3
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Arch/XFCE
Posts: 17,802

Rep: Reputation: 738Reputation: 738Reputation: 738Reputation: 738Reputation: 738Reputation: 738Reputation: 738
I did find the "s" syntax in the PERL rename command......
 
Old 11-15-2012, 10:01 PM   #4
towheedm
Member
 
Registered: Sep 2011
Location: Trinidad & Tobago
Distribution: Debian Jessie
Posts: 592

Rep: Reputation: 119Reputation: 119
Here's the regex for what you want:
Code:
's/(.*\/)(.{25}).*([.].*$)/$1$2$3/'
Pixellany: rename is an external command although it's not part of coreutils or any of the common Linux util. It is however a library call in stdio.h so Perl probably just uses that. It's included in Debian by default.
 
2 members found this post helpful.
Old 11-16-2012, 08:47 AM   #5
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Arch/XFCE
Posts: 17,802

Rep: Reputation: 738Reputation: 738Reputation: 738Reputation: 738Reputation: 738Reputation: 738Reputation: 738
Well....

My system has a "rename" command, but it does not seem to recognize the "s" syntax (and it's not in the man page)

Google finds a paucity of info on the version used above

Are you saying that the above version of rename is in fact a PERL script?
 
Old 11-16-2012, 09:24 PM   #6
towheedm
Member
 
Registered: Sep 2011
Location: Trinidad & Tobago
Distribution: Debian Jessie
Posts: 592

Rep: Reputation: 119Reputation: 119
You're correct!. It's a PERL script. Here's what I dug up on Debian Squeeze:
Code:
$ file /usr/bin/rename
/usr/bin/rename: symbolic link to `/etc/alternatives/rename'
$ ls -l /etc/alternatives/rename
lrwxrwxrwx 1 root root 16 Nov 19  2011 /etc/alternatives/rename -> /usr/bin/prename
$ file /usr/bin/prename 
/usr/bin/prename: a /usr/bin/perl -w script text executable
The script:
Code:
$ cat /usr/bin/prename
#!/usr/bin/perl -w
#
#  This script was developed by Robin Barker (Robin.Barker@npl.co.uk),
#  from Larry Wall's original script eg/rename from the perl source.
#
#  This script is free software; you can redistribute it and/or modify it
#  under the same terms as Perl itself.
#
# Larry(?)'s RCS header:
#  RCSfile: rename,v   Revision: 4.1   Date: 92/08/07 17:20:30 
#
# $RCSfile: rename,v $$Revision: 1.5 $$Date: 1998/12/18 16:16:31 $
#
# $Log: rename,v $
# Revision 1.5  1998/12/18 16:16:31  rmb1
# moved to perl/source
# changed man documentation to POD
#
# Revision 1.4  1997/02/27  17:19:26  rmb1
# corrected usage string
#
# Revision 1.3  1997/02/27  16:39:07  rmb1
# added -v
#
# Revision 1.2  1997/02/27  16:15:40  rmb1
# *** empty log message ***
#
# Revision 1.1  1997/02/27  15:48:51  rmb1
# Initial revision
#

use strict;

use Getopt::Long;
Getopt::Long::Configure('bundling');

my ($verbose, $no_act, $force, $op);

die "Usage: rename [-v] [-n] [-f] perlexpr [filenames]\n"
    unless GetOptions(
	'v|verbose' => \$verbose,
	'n|no-act'  => \$no_act,
	'f|force'   => \$force,
    ) and $op = shift;

$verbose++ if $no_act;

if (!@ARGV) {
    print "reading filenames from STDIN\n" if $verbose;
    @ARGV = <STDIN>;
    chop(@ARGV);
}

for (@ARGV) {
    my $was = $_;
    eval $op;
    die $@ if $@;
    next if $was eq $_; # ignore quietly
    if (-e $_ and !$force)
    {
	warn  "$was not renamed: $_ already exists\n";
    }
    elsif ($no_act or rename $was, $_)
    {
	print "$was renamed as $_\n" if $verbose;
    }
    else
    {
	warn  "Can't rename $was $_: $!\n";
    }
}

__END__

=head1 NAME

rename - renames multiple files

=head1 SYNOPSIS

B<rename> S<[ B<-v> ]> S<[ B<-n> ]> S<[ B<-f> ]> I<perlexpr> S<[ I<files> ]>

=head1 DESCRIPTION

C<rename>
renames the filenames supplied according to the rule specified as the
first argument.
The I<perlexpr> 
argument is a Perl expression which is expected to modify the C<$_>
string in Perl for at least some of the filenames specified.
If a given filename is not modified by the expression, it will not be
renamed.
If no filenames are given on the command line, filenames will be read
via standard input.

For example, to rename all files matching C<*.bak> to strip the extension,
you might say

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

To translate uppercase names to lower, you'd use

	rename 'y/A-Z/a-z/' *

=head1 OPTIONS

=over 8

=item B<-v>, B<--verbose>

Verbose: print names of files successfully renamed.

=item B<-n>, B<--no-act>

No Action: show what files would have been renamed.

=item B<-f>, B<--force>

Force: overwrite existing files.

=back

=head1 ENVIRONMENT

No environment variables are used.

=head1 AUTHOR

Larry Wall

=head1 SEE ALSO

mv(1), perl(1)

=head1 DIAGNOSTICS

If you give an invalid Perl expression you'll get a syntax error.

=head1 BUGS

The original C<rename> did not check for the existence of target filenames,
so had to be used with care.  I hope I've fixed that (Robin Barker).

=cut
The manpage:
Code:
$ man rename
RENAME(1)              Perl Programmers Reference Guide              RENAME(1)

NAME
       rename - renames multiple files

SYNOPSIS
       rename [ -v ] [ -n ] [ -f ] perlexpr [ files ]

DESCRIPTION
       "rename" renames the filenames supplied according to the rule specified
       as the first argument.  The perlexpr argument is a Perl expression
       which is expected to modify the $_ string in Perl for at least some of
       the filenames specified.  If a given filename is not modified by the
       expression, it will not be renamed.  If no filenames are given on the
       command line, filenames will be read via standard input.

       For example, to rename all files matching "*.bak" to strip the
       extension, you might say

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

       To translate uppercase names to lower, you'd use

               rename 'y/A-Z/a-z/' *

OPTIONS
       -v, --verbose
               Verbose: print names of files successfully renamed.

       -n, --no-act
               No Action: show what files would have been renamed.

       -f, --force
               Force: overwrite existing files.

ENVIRONMENT
       No environment variables are used.

AUTHOR
       Larry Wall

SEE ALSO
       mv(1), perl(1)

DIAGNOSTICS
       If you give an invalid Perl expression you'll get a syntax error.

BUGS
       The original "rename" did not check for the existence of target
       filenames, so had to be used with care.  I hope I've fixed that (Robin
       Barker).

perl v5.10.1                      2011-12-20                         RENAME(1)

Last edited by towheedm; 11-16-2012 at 09:28 PM.
 
Old 11-17-2012, 03:36 AM   #7
alaw005
LQ Newbie
 
Registered: Jul 2010
Posts: 2

Original Poster
Rep: Reputation: 0
Thanks towheedm, the regex worked a treat. I didn't realise I was using a PERL script, I came across it in a post somewhere. Once again, thanks for the help.
 
Old 12-23-2015, 10:27 AM   #8
mbnoimi
LQ Newbie
 
Registered: Nov 2012
Location: Syria
Distribution: Linux Mint XFCE
Posts: 28

Rep: Reputation: Disabled
Same problem

Guys I've same problem but I don't know how to use the above script

I've many files with long file name so rsync and many applications don't work fine with these long names.

May I get so help,
 
Old 12-23-2015, 01:03 PM   #9
norobro
Member
 
Registered: Feb 2006
Distribution: Debian Sid
Posts: 518

Rep: Reputation: 177Reputation: 177
Did you try the find command in post #1 using the regex from post #4?
Code:
find . -name '*' -print0 | xargs -0 rename -n 's/(.*\/)(.{25}).*([.].*$)/$1$2$3/' *
Note the "-n".
 
Old 12-23-2015, 01:40 PM   #10
mbnoimi
LQ Newbie
 
Registered: Nov 2012
Location: Syria
Distribution: Linux Mint XFCE
Posts: 28

Rep: Reputation: Disabled
Quote:
Originally Posted by norobro View Post
Did you try the find command in post #1 using the regex from post #4?
Code:
find . -name '*' -print0 | xargs -0 rename -n 's/(.*\/)(.{25}).*([.].*$)/$1$2$3/' *
Note the "-n".
I did that but the length of file name took as full path not just the file name only see this example:
Code:
./.local/share/Trash/files/cache/images/248741.banner.jpg renamed as ./.local/share/Trash/files/cache/images/248741.banne.jpg
This is totally wrong! 248741.banner.jpg shouldn't be rename!

UPDATED: Another wrong rename
Code:
./.kodi/userdata/Thumbnails/d/d524604e.jpg renamed as ./.kodi/userdata/Thumbnails/d/d52.jpg

Last edited by mbnoimi; 12-23-2015 at 01:49 PM.
 
Old 12-23-2015, 02:10 PM   #11
norobro
Member
 
Registered: Feb 2006
Distribution: Debian Sid
Posts: 518

Rep: Reputation: 177Reputation: 177
Try changing the second capture group from (.{25}) to (.{0,25})
 
Old 12-23-2015, 03:28 PM   #12
mbnoimi
LQ Newbie
 
Registered: Nov 2012
Location: Syria
Distribution: Linux Mint XFCE
Posts: 28

Rep: Reputation: Disabled
Quote:
Originally Posted by norobro View Post
Try changing the second capture group from (.{25}) to (.{0,25})
Still doesn't work
Code:
./.kodi/userdata/Thumbnails/8/8afbda1a.jpg renamed as ./.kodi/userdata/Thumbnails/8/8afbda1a
 
Old 12-23-2015, 04:32 PM   #13
norobro
Member
 
Registered: Feb 2006
Distribution: Debian Sid
Posts: 518

Rep: Reputation: 177Reputation: 177
Dunno.

Works fine here with sed:
Code:
$ echo "./.kodi/userdata/Thumbnails/8/8afbda1a.jpg" | sed -r 's/(.*\/+)(.{0,25}).*([.].*$)/\1\2\3/'
./.kodi/userdata/Thumbnails/8/8afbda1a.jpg
And in a simple script, to check perl:
Code:
#!/usr/bin/perl

my($text) = "./.kodi/userdata/Thumbnails/8/8afbda1a.jpg";
$text =~ m/(.*\/+)(.{0,25}).*([.].*$)/;
print $1 . $2 . $3 ."\n";
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] rename HIDDEN files recursively mrmnemo Linux - Software 26 09-17-2012 06:20 AM
Recursively rename some files mail4mz Programming 21 07-15-2011 11:18 AM
script to rename files recursively rs232 Linux - General 3 05-08-2011 03:05 PM
Rename recursively unihiekka Linux - Newbie 10 05-26-2010 02:55 AM
Unrar and Rename to Parent Folder Recursively Vasto Linux - Newbie 9 10-16-2008 07:36 AM


All times are GMT -5. The time now is 08:46 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration