tags:

views:

382

answers:

3

I have a directory that looks like this:

pages/
 folder1/
  folder1.filename1.txt
  folder1.filename2.txt
 folder2/
  folder2.filename4.txt
  folder2.filename5.txt
 folder3/
  filename6.txt

I want it to look like this:

pages/
 folder1/
  filename1.txt
  filename2.txt
 folder2/
  filename3.txt
  filename4.txt
 folder3/
  filename5.txt

With ls * | sed -e s/^[^.]*.// > /tmp/filenames.txt I get a file containing:

filename1.txt
filename2.txt
filename3.txt
filename4.txt
txt

How can I tell sed to ignore filenames of the form [filename].[suffix] and only look at filenames of the form [foldername].[filename].[suffix]?

The final script (as pointed out, the find command would simplify things, but this worked):

for folder in $(ls .)
do
    if test -d $folder
    then
     pushd $folder
       ls * | sed 's/.*\.\(.*\..*\)/\1/' > /tmp/filenames.txt
       ls * > /tmp/current.txt

       exec 3</tmp/current.txt
       exec 4</tmp/filenames.txt

       while read file <&3; read name <&4;
       do
        mv "$file" "$name"
       done

       rm /tmp/current.txt
       rm /tmp/filenames.txt
     popd
    else
     echo $folder "not a directory"
    fi
done

exit 0

This page is now a community wiki. You can add more elegant solutions below:

for folder in $(ls .)
do 
     something better
A: 

use the following regex:

/\A(.\*?\\.){2,2}.+\Z/
ennuikiller
Er, throws a syntax error. I don't know enough about regular expressions to know how to fix it.
msutherl
replace \A by ^ and \Z by $ and try again
ennuikiller
+3  A: 

Give this a try:

sed 's/.*\.\(.*\..*\)/\1/'

You should really use find then you wouldn't need the check for "-d folder" or the temp file and execs or the while loop.

You can avoid the temporary file by using process substition:

while read line
do
    echo $line
done < <(ls)

Another item of interest: your system may already have a Perl script called rename or prename which will rename files using a regular expression.

Dennis Williamson
That did the trick. I look into using find next time I have to do something like this. Not knowing regexp is an annoying hinderance. Thanks!
msutherl
+2  A: 

You don't need to use sed:

ls * > /tmp/current.txt
exec 3</tmp/current.txt
while read file <&3;
do
    replacement=${file#${folder}.}
    if [ "$replacement" != "txt" ] ; then
        mv "$file" "$replacement"
    fi
done
Douglas Leeder
Will gives this a shot. Thanks.
msutherl
Ah, the issue with this method is that there are some cases where I have this: Folder1/Folder1.txt. This method renames those files "txt".
msutherl
You said you wanted to remove "Folder1." prefix :-).
Douglas Leeder
I know, I wasn't clear. Thanks anyhow! ;)
msutherl