Renaming files


 
Thread Tools Search this Thread
Top Forums UNIX for Advanced & Expert Users Renaming files
# 1  
Old 10-21-2010
Renaming files

Hello

Please can someone help.
We are being sent a directiory full of images.
The names of these images can vary in length and have spaces in them.
example:
nn 999999 nnnnn nnnn nnnn nn nnn nnn nn nnnn.pdf
what we want to do is rename all the images. Take the first two fields nn 999999 and replace the space with and underscore.
nn_999999
# 2  
Old 10-21-2010
This is an overkill version, handling every usually invisible byte for the low 128 except NULL, just for the educational value. A file can be named almost anything, but it can be referenced as ./'name' even if it start with -, unless it contains ', and that can be escaped "'".

Single quoting is most literal, has no metacharacters but itself, is faster for the shell to process, and should always be the first choice.

Unfortuantely, single and double quotes concatenated are hard to read in this font. In a single quoted string like my inline single quoted string as sed script, a single quote is single-double-single-double-single, single to get out of single quoting, add a single in double quotes, and single to get back into single quoting.

This code makes a script for you to review before running in the target dir. The script makes a new dir of files to review before moving them in place of the originals. Making a new dir means there is ***no risk*** until you replace the files manually. If duplicate names are generated, you may want to tinker with the list of acceptable file name characters, or just hack the output script and rerun.

Code:
(
echo '#!/usr/bin/ksh
rm -rf /tmp/rename_out.$LOGNAME
mkdir /tmp/rename_out.$LOGNAME
'

ls *.pdf| sed '
  s/'"'"'/"&"/g
 ' | sed '
  :loop
  /\.pdf$/!{
    N
    s/\n/'"'"'?'"'"'/
    b loop
   }
  p
  s/"'"'"'"/_/g
  s/'"'"'?'"'"'/_/g
  s/[^A-Za-z0-9_.]/_/g
  s/___*/_/g
 ' | sed '
  N
  s/\(.*\)\n/cp -p '.\/\1' \/tmp\/rename_out.'$LOGNAME'/
 ' 
 chmod u+x /tmp/rename_out_$LOGNAME.sh
) >/tmp/rename_out_$LOGNAME.sh

Narrative: Using parentheses to concatenate output as follows into a script in /tmp with your id in the name:
echo commands to build a ksh script that will first:
Destroy any old tmp output dir,
Make empty new tmp output dir.
Generate cp commands to make files with old content and new names:
list all pdf files in the current dir and pass (one file per line unless line feed in file name) to sed #1, which
wraps any ' in ", and then pipe carries that to sed #2, which
if no .pdf suffix on line, loops picking up all of any file name with linefeeds in it, and in place of the embedded linefeed puts the one character glob ? outside anticipated single quotes,
spits out this as the odd (source name) line to sed #3,
reworks that line to build the target name:
replace the embedded single quotes with underscode,
replace the embedded linefeeds with underscore,
replace every character not a letter, number, underscore or dot to be one underscore,
replace multiple underscores with one,
and passes it on to sed #3 as even lines,
sed #3 gets the odd-even pair of lines in the buffer,
change the two lines to cp -p ./'first_line' /tmp/outdir/second_line
changes the generated script to user executable.
This User Gave Thanks to DGPickett For This Post:
# 3  
Old 10-21-2010
Another approach.
Assuming that the final filenames will be "nn_999999.pdf" rather than something else.

Check thoroughly before running on live data. Remove "echo" on the "mv" line when sure.
Note that a script of this nature is a "one off" and cannot be run a second time on the same directory.

Code:
ls -1 *\.pdf | while read old_filename
do
        part1=`echo "${old_filename}"|awk '{print $1}'`
        part2=`echo "${old_filename}"|awk '{print $2}'`
        new_filename="${part1}_${part2}.pdf"
        # Remove echo when tested
        if [ ! -f "${new_filename}" ]
        then
                if [ -f "${old_filename}" ]
                then
                       echo mv "${old_filename}" "${new_filename}"
                fi
        else
                echo "Error: Duplicate new filename: ${old_filename}"
        fi
done

This User Gave Thanks to methyl For This Post:
# 4  
Old 10-21-2010
Well, mv is always a bit riskier than cp, as you have no undo, but you could make that a cp script so easy. This is a simple spaces to underscores shell-ish solution. With cp, you do not have to worry there are no spaces in some names:

Code:
ls *.pdf|while [ 1 ]
do
 zf=$(line)
 zfn=$( echo "$zf" |tr ' ' '_' )
 cp -p "$zf" "$newdir/$zfn"
done

# 5  
Old 10-21-2010
Code:
ls -1 *.pdf | while read a
do
b=$(echo "$a" | sed 's|  *| |g;s|^\([^ ][^ ]*\) \([^ ][^ ]*\) .*|\1_\2\.pdf|')
eval echo 'mv "$a" "$b"' >>rename.sh
done

check rename.sh and if the content is OK , run it

Code:
sh rename.sh

As stated by DGnitPick, you can change mv by cp in my code for more safty

Last edited by ctsgnb; 10-21-2010 at 03:06 PM.. Reason: add cruch of many space into one
# 6  
Old 10-21-2010
Does awk consider every space char is a field sep, or does this implicity crush many spaces to one _, and only one set of spaces per line?

Quote:
Originally Posted by methyl
Another approach.
Assuming that the final filenames will be "nn_999999.pdf" rather than something else.

Check thoroughly before running on live data. Remove "echo" on the "mv" line when sure.
Note that a script of this nature is a "one off" and cannot be run a second time on the same directory.

Code:
ls -1 *\.pdf | while read old_filename
do
        part1=`echo "${old_filename}"|awk '{print $1}'`
        part2=`echo "${old_filename}"|awk '{print $2}'`
        new_filename="${part1}_${part2}.pdf"
        # Remove echo when tested
        if [ ! -f "${new_filename}" ]
        then
                if [ -f "${old_filename}" ]
                then
                       echo mv "${old_filename}" "${new_filename}"
                fi
        else
                echo "Error: Duplicate new filename: ${old_filename}"
        fi
done



---------- Post updated at 01:59 PM ---------- Previous update was at 01:57 PM ----------




I hesitated to use read, and used line, as read can remove whitespace.
Quote:
Originally Posted by ctsgnb
Code:
ls * | while read a
do
b=$(echo "$a" | sed 's|^\([^ ][^ ]*\) \([^ ][^ ]*\) .*|\1_\2\.pdf|')
eval echo 'mv "$a" "$b"' >rename.sh
done

check rename.sh and if the content is OK , run it

sh rename.sh


---------- Post updated at 02:07 PM ---------- Previous update was at 01:59 PM ----------




Eyeballing a mv file might miss some. Nobody suggested ln and an output dir on the same mount in place of cp. After all, mv within a device is ln (link()) + rm (unlink()). If you like newdir, you can rename the dirs and keep the original in case there are concerns.

Code:
rm -rf ../newdir
mkdir ../newdir
ls *.pdf|while [ 1 ]
do
 zf=$(line)
 zfn=$( echo "$zf" |tr ' ' '_' )
 ln "$zf" ../newdir/"$zfn"
done

This is becoming a reference on the subject of renaming files. Smilie
# 7  
Old 10-21-2010
I used double quote in my code
Code:
# read a
titi toto tutu          tata    tutut
# echo $a
titi toto tutu tata tutut
# echo "$a"
titi toto tutu          tata    tutut
#



---------- Post updated at 08:13 PM ---------- Previous update was at 08:11 PM ----------




Note that i meanwhile changed the code you embbeded
Code:
ls -1 *.pdf | while read a
do
b=$(echo "$a" | sed 's|  *| |g;s|^\([^ ][^ ]*\) \([^ ][^ ]*\) .*|\1_\2\.pdf|')
eval echo 'mv "$a" "$b"' >>rename.sh
done



---------- Post updated at 08:15 PM ---------- Previous update was at 08:13 PM ----------




i didn't know about that $(line) stuff : could you tell me more ?
Code:
while [ 1 ]   <--- does it read only line 1 or does it goes until it cannot read anymore ?
do
read $(line)

done


Last edited by ctsgnb; 10-21-2010 at 03:32 PM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Renaming multiple files in sftp server in a get files script

Hi, In sftp script to get files, I have to rename all the files which I am picking. Rename command does not work here. Is there any way to do this? I am using #!/bin/ksh For eg: sftp user@host <<EOF cd /path get *.txt rename *.txt *.txt.done ... (7 Replies)
Discussion started by: jhilmil
7 Replies

2. Shell Programming and Scripting

Renaming files

Hello, I am looking for a command line that will rename name files : f700_abc_o_t_MASTERID_AS_AE_20130323.csv like this f700_abc_o_t_MASTERID_AS_AE_20130324.csv The great idea could be to get the date stamp 20130323 and change any part of it, instead of just change the... (4 Replies)
Discussion started by: Aswex
4 Replies

3. Shell Programming and Scripting

renaming files

Hi, I have a list of files in a folder with the same name ending (over 1000 files) joe.jpy.jpeg joe1.jpy.jpeg joe2.jpy.jpeg jon3.jpy.jpeg jor5.jpy.jpeg .....jpy.jpeg etc. I want to change jpy to hhk So the output will be: joe.hhk.jpeg joe1.hhk.jpeg joe2.hhk.jpeg jon3.hhk.jpeg... (3 Replies)
Discussion started by: kylle345
3 Replies

4. Shell Programming and Scripting

renaming files or adding a name in the beginning of all files in a folder

Hi All I have a folder that contains hundreds of file with a names 3.msa 4.msa 21.msa 6.msa 345.msa 456.msa 98.msa ... ... ... I need rename each of this file by adding "core_" in the begiining of each file such as core_3.msa core_4.msa core_21.msa (4 Replies)
Discussion started by: Lucky Ali
4 Replies

5. Shell Programming and Scripting

renaming files

Hi all, using a utility image file was named starting with blank space and a blank space in between. I want to rename the files. file names are in the format " sb 12.tif"," sb 13.tif"," sb 14.tif" the files are in thousands. i want to rename as 12.tif, 13.tif, 14.tif.... thanks. (3 Replies)
Discussion started by: ahkverma
3 Replies

6. UNIX for Dummies Questions & Answers

renaming files

I have a list of files named ab_*.csv I would like to remane them all by removing the ab_ and have *.csv I did the following but I am surely missing something. /* wrong script */ for i in `ls -1 ab_*`; do mv ab_$i $i; done Thanks in advance. (1 Reply)
Discussion started by: jxh461
1 Replies

7. UNIX for Dummies Questions & Answers

Renaming files

Hello! I am not familiar with UNIX and I have this problem: I need to move files from a UNIX machine to a PC. UNIX file names contain ":" as special character which is not recognized in a PC. How can I change ":" for "_" in the name of a bunch of files in UNIX? Thanks for your help. (7 Replies)
Discussion started by: Tygoon
7 Replies

8. UNIX for Dummies Questions & Answers

renaming files

directory name = /usr/tom/1997 files - ABC_1997_ST1_BCD.SQL BCD_1997_ST1_EFG_SAB.SQL TTT_EBC_1997_ST1_A.SQL sub directory - /usr/tom/1997/jan a) I want to just rename the all files ending with '.SQL' and also its contents in the 1997 directory(excluding subdirectories eg... (3 Replies)
Discussion started by: systemsb
3 Replies

9. UNIX for Dummies Questions & Answers

renaming the files

Hi All, Today I got a small problem while handling zipped files in PROD support. There are files in this format and I had to grep them reading some contents A.B.gz.C.D where A,B,C and D stand for variables (like FIRST.NAME.gz.MIDDLE.LAST). I know that these files are zipped files and If I... (1 Reply)
Discussion started by: adurga
1 Replies

10. UNIX for Dummies Questions & Answers

renaming files

i have a set of *.lst files. now i want to change the names from "lst" to "dat". how to do it? ex.: -rw-r--r-- 1 rram group 22 Sep 21 13:10 a.lst -rw-r--r-- 1 rram group 22 Sep 21 13:09 b.lst -rw-r--r-- 1 rram group 22 Sep 21 13:10 c.lst... (4 Replies)
Discussion started by: raguramtgr
4 Replies
Login or Register to Ask a Question