LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Slackware
User Name
Password
Slackware This Forum is for the discussion of Slackware Linux.

Notices


Reply
  Search this Thread
Old 03-04-2014, 03:54 PM   #1
stf92
Senior Member
 
Registered: Apr 2007
Location: Buenos Aires.
Distribution: Slackware
Posts: 4,442

Rep: Reputation: 76
Renaming a set of files.


Hi: I have a set of files under the same directory, all filenames beginning with the same prefix. How could I take away the prefix from all the filenames?

All I need is a way to do the operation for only one file, as then I could write a script to do the same within a loop.

Last edited by stf92; 03-04-2014 at 03:57 PM.
 
Old 03-04-2014, 04:12 PM   #2
stf92
Senior Member
 
Registered: Apr 2007
Location: Buenos Aires.
Distribution: Slackware
Posts: 4,442

Original Poster
Rep: Reputation: 76
OK. Sed is the answer.
 
Old 03-04-2014, 10:54 PM   #3
Richard Cranium
Senior Member
 
Registered: Apr 2009
Location: McKinney, Texas
Distribution: Slackware64 15.0
Posts: 3,858

Rep: Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225
See "man rename"
 
Old 03-05-2014, 04:21 AM   #4
kikinovak
MLED Founder
 
Registered: Jun 2011
Location: Montpezat (South France)
Distribution: CentOS, OpenSUSE
Posts: 3,453

Rep: Reputation: 2154Reputation: 2154Reputation: 2154Reputation: 2154Reputation: 2154Reputation: 2154Reputation: 2154Reputation: 2154Reputation: 2154Reputation: 2154Reputation: 2154
Quote:
Originally Posted by stf92 View Post
Hi: I have a set of files under the same directory, all filenames beginning with the same prefix. How could I take away the prefix from all the filenames?

All I need is a way to do the operation for only one file, as then I could write a script to do the same within a loop.
If you use the Xfce desktop, there's a nifty graphical application for just what you are trying to do: Thunar Bulk Rename. I use it all the time for mass-renaming music files for my car stereo's USB stick, which can't handle subdirectories.
 
Old 03-05-2014, 04:44 AM   #5
eloi
Member
 
Registered: Nov 2010
Posts: 227

Rep: Reputation: 61
I do not remember where I found this perl script (sorry to the author):

Code:
#!/usr/bin/perl

($regexp = shift @ARGV) || die "Usage:  rename perlexpr [filenames]\n";

if (!@ARGV) {
	@ARGV = <STDIN>;
	chomp(@ARGV);
}


foreach $_ (@ARGV) {
	$old_name = $_;
	eval $regexp;
	die $@ if $@;
	rename($old_name, $_) unless $old_name eq $_;
}

exit(0);
This script is more complete (it allows you to use regex) than the rename
version that comes with Slackware.

(Put it in ~/bin and rename it to i.e. prename)
 
Old 03-05-2014, 09:41 AM   #6
lems
Member
 
Registered: May 2004
Distribution: BSD
Posts: 269

Rep: Reputation: 119Reputation: 119
If in the future you might need to rename files again, you might also want to check out rename: a perl script by ex-Slackware user Aristotle Pagaltzis. There's also a tutorial.
 
2 members found this post helpful.
Old 03-05-2014, 03:30 PM   #7
rkfb
Member
 
Registered: Oct 2003
Location: Guildford, England
Distribution: Slackware64 15.0 running i3
Posts: 494

Rep: Reputation: 174Reputation: 174
Quote:
Originally Posted by lems View Post
If in the future you might need to rename files again, you might also want to check out rename: a perl script by ex-Slackware user Aristotle Pagaltzis. There's also a tutorial.
Although you might want to rename it first to avoid conflict with the stock rename in /usr/bin
 
Old 03-06-2014, 09:30 AM   #8
stf92
Senior Member
 
Registered: Apr 2007
Location: Buenos Aires.
Distribution: Slackware
Posts: 4,442

Original Poster
Rep: Reputation: 76
Thanks for suggesting 'rename'. But could somebody tell me what's the problem with this script?:
Code:
semoi@server:~/STORE1/Nonsoft/libros/chess/nuevo$ cat ren.sh
#!/bin/bash

# PROG APPL: Rename a set of files.

# El script es poco flexible. No tiene argumentos de entrada. It's hard
# coded. In current dir there are
# Averbakh,\ Yuri\ -\ Comprehensive\ 1.djvu
# Averbakh,\ Yuri\ -\ Comprehensive\ 2.djvu
# Averbakh,\ Yuri\ -\ Comprehensive\ 3.djvu

# The script renames them to
# BOOK01
# BOOK02
# BOOK03
# s is sed's substitute command, like s in vim.

LIST="$(ls Aver*)" #ls  interpretado como orden por los parentesis
for i in "$LIST" ; do
        INPUT="$i"
        OUTPUT=$(echo "$INPUT" | tr ' ' '_')
#        OUTPUT=$(echo "$OUTPUT" | sed s/Averbakh,_Yuri_-_Comprehensive_//)
#        mv "$INPUT" "$OUTPUT"	
        echo -n "Output= "
        echo "$OUTPUT"
done
# The second command could be tr as well, or both commands sed. Either
# tr or sed can be used in both lines.

#Averbakh,\ Yuri\ -\ Comprehensive\ Chess\ Endings\ 1\ -\ Bishop\ &\ Knight\ Endings.pdf*

semoi@server:~/STORE1/Nonsoft/libros/chess/nuevo$
It should replace spaces with underscores ('_'). OUTPUT should contain a single filename. However, the loop is traversed only once, which makes me think OUTPUT contains all of the filenames concatenated:
Code:
semoi@server:~/STORE1/Nonsoft/libros/chess/nuevo$ ./ren.sh
Output= Averbakh,_Yuri_-_Comprehensive_Chess_Endings_1_-_Bishop_&_Knight_Endings.pdf
Averbakh,_Yuri_-_Comprehensive_Chess_Endings_1_-_Bishop_&_Knight.djvu
Averbakh,_Yuri_-_Comprehensive_Chess_Endings_2_-_Bishop_vs_Knight,_Rook_vs_Minor_Pieces.pdf
Averbakh,_Yuri_-_Comprehensive_Chess_Endings_3_-_Queen_Endings.djvu
Averbakh,_Yuri_-_Comprehensive_Chess_Endings_3_-_Queen_Endings.txt
Averbakh,_Yuri_-_Comprehensive_Chess_Endings_3_-_Queen_Endings.txt~
Averbakh,_Yuri_-_Comprehensive_Chess_Endings_4_-_Pawn_Endings.djvu
Averbakh,_Yuri_-_Comprehensive_Chess_Endings_4_-_Pawn_Endings.pdf
Averbakh,_Yuri_-_Comprehensive_Chess_Endings_5_-_Rook_Endings.pdf
semoi@server:~/STORE1/Nonsoft/libros/chess/nuevo$
As you can see, the constant "Output= " is output only once!
 
Old 03-06-2014, 09:34 AM   #9
Richard Cranium
Senior Member
 
Registered: Apr 2009
Location: McKinney, Texas
Distribution: Slackware64 15.0
Posts: 3,858

Rep: Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225
Your loop is only looping once. Put an "echo $i" at the beginning of the loop to verify.
 
Old 03-06-2014, 11:21 AM   #10
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
An aside note: the lines
Code:
LIST="$(ls Aver*)"
for i in $LIST ; do
can be condensed into
Code:
for i in Aver* ; do
 
1 members found this post helpful.
Old 03-07-2014, 03:28 AM   #11
eloi
Member
 
Registered: Nov 2010
Posts: 227

Rep: Reputation: 61
In Resume

Code:
for i in Aver* ; do
	mv "$i" `echo "$i" | tr ' ' '_'`
done
 
Old 03-07-2014, 04:36 AM   #12
stf92
Senior Member
 
Registered: Apr 2007
Location: Buenos Aires.
Distribution: Slackware
Posts: 4,442

Original Poster
Rep: Reputation: 76
Quote:
Originally Posted by colucix View Post
An aside note: the lines
Code:
LIST="$(ls Aver*)"
for i in $LIST ; do
can be condensed into
Code:
for i in Aver* ; do
Writing it in the condensed form solves the problem. I mean, now the loop is traveled as many times as there are files in the directory. But now I want to know what the trouble is with
Code:
LIST="$(ls Aver*)"
for i in "$LIST" ; do
Why is the loop traveled only once? If I write $LIST without quotes then the spaces in the filenames make the loop to be traveled once for every word in the filename.
 
Old 03-07-2014, 05:07 AM   #13
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Quote:
Originally Posted by stf92 View Post
Why is the loop traveled only once? If I write $LIST without quotes then the spaces in the filenames make the loop to be traveled once for every word in the filename.
If you use quotes the whole list is taken as a single word! To avoid problems with blank spaces, either change the IFS variable or use a while read loop, redirecting standard input from <(find Aver*).
 
Old 03-07-2014, 05:16 AM   #14
55020
Senior Member
 
Registered: Sep 2009
Location: Yorks. W.R. 167397
Distribution: Slackware
Posts: 1,307
Blog Entries: 4

Rep: Reputation: Disabled
Quote:
Originally Posted by stf92 View Post
Code:
LIST="$(ls Aver*)"
for i in "$LIST" ; do
Why is the loop traveled only once? If I write $LIST without quotes then the spaces in the filenames make the loop to be traveled once for every word in the filename.
When you store the list of filenames in a variable, there is no way of telling the difference between (1) spaces that were inside filenames, and (2) spaces that were between filenames. They are indistinguishable. A space is a space, it does not have a homoeopathic memory of whether it used to be inside a filename or between two filenames. You can either quote the whole lot as a single string, or not quote it as a list of words. There is no other choice.

The usual ways out of this problem are (a) don't allow spaces in your filenames, (b) use shell filename expansion like eloi showed you, (c) use an array (bash-specific, read the manual), (d) if you are writing a script, set the positional parameters (set -- Aver*) and use them as "$@", (e) use the find command with '-print0' and the xargs command with --null (read the manual for details).

If you are now feeling a bit sick, this is why most people choose option (a).

Note also that if there are *no* matching files, shell filename expansion of 'Aver*' will return the string 'Aver*' and the loop will be executed once with i='Aver*' (which does not exist). This might give the user a helpful error message, or it might cause an unhelpful error. To avoid this, test the value of i within the loop and do nothing if it equals 'Aver*', or set the shell option 'nullglob'.
 
Old 03-07-2014, 05:25 AM   #15
55020
Senior Member
 
Registered: Sep 2009
Location: Yorks. W.R. 167397
Distribution: Slackware
Posts: 1,307
Blog Entries: 4

Rep: Reputation: Disabled
Quote:
Originally Posted by colucix View Post
If you use quotes the whole list is taken as a single word! To avoid problems with blank spaces, either change the IFS variable or use a while read loop, redirecting standard input from <(find Aver*).
while read has its own problems -- it will strip any spaces from the start of each filename and collapse multiple spaces inside filenames

IFS is a game you can't win. Choose any random character that you *can't* have in your filenames. Are you feeling lucky?
 
  


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
Help renaming files nandelbosc Programming 2 11-26-2009 07:24 AM
Renaming files leupi Linux - General 5 09-16-2008 03:22 AM
help renaming files please balistic Linux - Newbie 2 07-29-2007 03:35 PM
help renaming files balistic Linux - Newbie 4 07-29-2007 08:04 AM
Renaming files in one go saurya_s Linux - Software 1 01-12-2004 01:16 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Slackware

All times are GMT -5. The time now is 09:08 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
Open Source Consulting | Domain Registration