views:

161

answers:

6

I need to remove the extension ".tex":

./1-aoeeu/1.tex
./2-thst/2.tex
./3-oeu/3.tex
./4-uoueou/4.tex
./5-aaa/5.tex
./6-oeua/6.tex
./7-oue/7.tex

Please, do it with some tools below:

  1. Sed and find

  2. Ruby

  3. Python

My Poor Try:

$find . -maxdepth 2 -name "*.tex" -ok mv `sed '[email protected]@@g' {}` {} +
+4  A: 

A Python script to do the same:

import os.path, shutil

def remove_ext(arg, dirname, fnames):
    argfiles = (os.path.join(dirname, f) for f in fnames if f.endswith(arg))
    for f in argfiles:
        shutil.move(f, f[:-len(arg)])

os.path.walk('/some/path', remove_ext, '.tex')
ars
+1  A: 

One way, not necessarily the fastest (but at least the quickest developed):

    pax> for i in *.c */*.c */*/*.c ; do
    ...> j=$(echo "$i" | sed 's/\.c$//')
    ...> echo mv "$i" "$j"
    ...> done

It's equivalent since your maxdepth is 2. The script is just echoing the mv command at the moment (for test purposes) and working on C files (since I had no tex files to test with).

Or, you can use find with all its power thus:

    pax> find . -maxdepth 2 -name '*.tex' | while read line ; do
    ...> j=$(echo "$line" | sed 's/\.tex$//')
    ...> mv "$line" "$j"
    ...> done

paxdiablo
+1, for "while read line", i was messing up with `-exec`
nik
Agreed. "find ... | while read ..." is one of my favorite bash one-liner templates.
Jefromi
A: 

Using bash, find and mv from your base directory.

 for i in $(find . -type f -maxdepth 2 -name "*.tex"); 
 do 
    mv $i $(echo "$i" | sed 's|.tex$||'); 
 done


Variation 2 based on other answers here.

find . -type f -maxdepth 2 -name "*.tex" | while read line; 
do 
   mv "$line" "${line%%.tex}";  
done


PS: I did not get the part about escaping '.' by pax...

nik
I see three problems here (1) Is that gz supposed to be a tex? (2) No handling of files with spaces. (3) The . should be escaped. All fixable, just be aware of them.
paxdiablo
@nik, it turns out the escaping doesn't actually matter in this case. Normally when you use the sed s// command, "." will match *any* character. But since you're matching ".tex$" (end of line) and the find only produces lines ending in .tex, the any-char "." will alway be a literal ".". It's only an issue if find generated something like "xx.latex" where the ".tex" would match "atex". But find doesn't, so you're okay. I am unsure however of how "*.tex" will be treated if the current directory has *.tex files - the shell may expand them before find sees it - that's why I always use '*.tex'.
paxdiablo
A: 

Using "for i in" may cause "too many parameters" errrors

A better approach is to pipe find onto the next process.

Example:

find . -type f -name "*.tex" | while read file
do
    mv $file ${file%%tex}g
done

(Note: Wont handle files with spaces)

toolkit
A: 

There's an excellent Perl rename script that ships with some distributions, and otherwise you can find it on the web. (I'm not sure where it resides officially, but this is it). Check if your rename was written by Larry Wall (AUTHOR section of man rename). It will let you do something like:

find . [-maxdepth 2] -name "*.tex" -exec rename 's/\.tex//' '{}' \;

Using -exec is simplest here because there's only one action to perform, and it's not too expensive to invoke rename multiple times. If you need to do multiple things, use the "while read" form:

find . [-maxdepth 2] -name "*.tex" | while read texfile; do rename 's/\.tex//' $texfile; done

If you have something you want to invoke only once:

find . [-maxdepth 2] -name "*.tex" | xargs rename 's/\.tex//'

That last one makes clear how useful rename is - if everything's already in the same place, you've got a quick regexp renamer.

Jefromi
A: 

In Ruby, to rename the file:

def rename_tex(dir)
  Dir.entries(dir).each do |file|
    if file =~ /*\.tex$/
      File.rename(file, file[0, file.rindex('.')])
    end
  end
end

To just remove the extension (might not be exactly what you want, since your example has a . in the directory name):

def remove_tex(dir)
  Dir.entries(dir).collect do |file|
    if file =~ /*\.tex$/
      full_path = File.expand_path(file)
      full_path[0, full_path.rindex('.')]
    end
  end.compact
end
maksim