views:

298

answers:

4

On Ubuntu, I have a bunch of files in a tree all called 'output.txt'. For each file I want to sort the lines alphabetically with 'sort'. I considered

find . -name output.txt -exec sort{} \;

but this outputs the sorted lines to the console rather than updating the original files which is what I want.

A: 

I haven't used Linux a whole lot, so I might be mistaken, but shouldn't you be able to control that with StdOut?

find . -name output.txt -exec sort{} \ > output.txt
Tomas Lycken
The above will produce all the sorted lines in a single file, not sort each file.
kbyrd
wouldn't 'sort -o' help you here?
kbyrd
A: 

Try this

csh <enter>

foreach i ( `find . -type f -name output.txt -print`) <enter>
   cat $i | sort > $.sorted <enter>
end <enter>

you will generate a sorted copy of your file.

Luixv
now is correct. The previous version generated only ONE file with all the lines together. Sorry.
Luixv
+3  A: 
find . -name output.txt -exec sort{} -o{} \;
fortran
Looks like it's working (will take a while so can't be sure). I could have sworn I tried something similar to that (isn't that always the way?) Anyway you rock.
Jim Blackler
Can you really use sort to use the same outputfile as the inputfile? I doubt it.
lothar
@lothar whatever you doubt it or not, it will still work :-p the sort program reads the whole file, sorts the lines in memory and then writes the output
fortran
+1  A: 

Fortran,

I would do it a little differently, I would not sort the file into itself. Just incase anything new gets added to the files after the sort. here is what I would do:

  • mirrior the dir tree that has a 'output.txt' file and put the sorted file there

like so:

#!/bin/bash 

LIST=`find $1 -name output.txt`

for i in $LIST ; do
        X=`dirname $i`
        mkdir -p "sorted/$X"
        sort "$i" -o "sorted/$i"
done

the above needs a bit of polish, mkdir should have an 'if' around it and $1 should be checked for sanity

gives you this:

orignal:

mytest
mytest/ccc
mytest/ccc/f
mytest/ccc/f/output.txt
mytest/ccc/d
mytest/ccc/d/output.txt
mytest/ccc/e
mytest/ccc/e/output.txt
mytest/bbb
mytest/bbb/f
mytest/bbb/d
mytest/bbb/e
mytest/aaa
mytest/aaa/f
mytest/aaa/f/output.txt
mytest/aaa/d
mytest/aaa/d/output.txt
mytest/aaa/e
mytest/aaa/e/output.txt

Output:

sorted
sorted/mytest
sorted/mytest/ccc
sorted/mytest/ccc/f
sorted/mytest/ccc/f/output.txt
sorted/mytest/ccc/d
sorted/mytest/ccc/d/output.txt
sorted/mytest/ccc/e
sorted/mytest/ccc/e/output.txt
sorted/mytest/aaa
sorted/mytest/aaa/f
sorted/mytest/aaa/f/output.txt
sorted/mytest/aaa/d
sorted/mytest/aaa/d/output.txt
sorted/mytest/aaa/e
sorted/mytest/aaa/e/output.txt

one last thing I think the sort output file is writen to a tmp file and then renamed when the sort is done, otherwise the output file could truncate the input file before everything was read. Like sed's inplace option.

ms4720