Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have a directory tree of files I need to loop through and reformat the lines. can I do this with sed with some combination of find?

for each file, I'll need to adjust the text in the file from

...
* @category Foo
* @package Bar
...

into just this (Remove the @category line, but prepend the value to the package annotation value)

...
* @package Foo/Bar
...

what is the most efficient way of doing this? its a few hundred files that will be modified.

share|improve this question
    
I don't know how to use sed, but if you are able to write a bash script, which does this operation for one file, you can do it for every file in the directory tree by using "find ./ -exec bash-script {} \;" –  FSMaxB Dec 19 '12 at 20:53

3 Answers 3

When you have to work on multiple lines, comes in mind, it's more suitable than sed to do this.

awk '/^\* +@package/{print $0"/"v;next} {if ($0 ~ /^\* +@category/){v=$3}else{print}}' file.txt

Or decomposed :

awk '
    /^\* +@package/{
        print $0"/"v
        next
    }
    {
        if ($0 ~ /^\* +@category/){
            v=$3
        }
        else{
            print
        }
    }
' file.txt
share|improve this answer
    
One True awk :) –  befree42 Dec 19 '12 at 21:23

Try this:

sed '/@category/{s/.*@category /* @package /;N;s/\n.*@package /\//}'

To run this against all the files in a whole tree, I would do something like this:

for i in $(find . -type f); do
   sed '/@category/{s/.*@category /* @package /;N;s/\n.*@package /\//}' $i > $i.new
   mv $i.new $i
done
share|improve this answer
    
Nice work. But since he's using Linux (GNU sed), why wouldn't you use sed -i to replace inline, and do away with the loop using find -type f -exec sed -i ... {} + ? –  tink Dec 19 '12 at 21:27
    
Sure, you can do that. Largely a matter of taste. But that is a non-standard extension and that bit of knowledge about sed is less generally useful than knowing how to use a for loop. Also, explicitly looping also gives you the chance, if you want, to modify the behavior to preview what will happen (by removing the mv statement) or undo it (if you add a mv $i $i.old). –  Nicole Hamilton Dec 19 '12 at 21:41

This might work for you (GNU sed):

find . -type f -exec sed -ri '$!N;s/^\* @category (.*)\n(\* @package )(.*)/\2\1\/\3/;P;D' {} \;
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.