3

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.

1
  • 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, 2012 at 20:53

3 Answers 3

2

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
2
  • 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, 2012 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). Dec 19, 2012 at 21:41
0

This might work for you (GNU sed):

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

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
1
  • One True awk :)
    – user151547
    Dec 19, 2012 at 21:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .