Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a command find "$PWD" -name __openerp__.py|awk -F/ -vOFS=/ 'NF-=2'|sort -u and I want to take a certain line containing /web/addons and push it to the front of output then do the same with /openerp/addons making so that line with /openerp/addons would be first and line with /web/addons would be second.

I figured to use grep with that input and from the same output - grep with wildcard and exclude, but yet to figure out how to pass pipe output to multiple greps. Also there is probably multiple ways of doing this.

So right now I get:

<my path>/addons
<my path>/development
<my path>/external
<my path>/server/openerp/addons
<my path>/web/addons

And I want it to become:

<my path>/server/openerp/addons
<my path>/web/addons
<my path>/addons
<my path>/development
<my path>/external

P.S. Reversal of sort will not solve this

share|improve this question
    
This will not work in a pipeline: it needs to buffer all output lines until it finds the ones you're interested in before outputting anything. –  Joseph R. Jan 29 at 14:02
    
actually I'm fine to hold buffer in /tmp/. I'm mainly interested in it being one liner. –  JackLeo Jan 29 at 14:09
add comment

3 Answers

I'm not sure I understand what you're trying to do here but if all you want is to have the line with /openerp/addons to be first and /web/addons to be second, why not just something like this:

find "$PWD" -name '__openerp__.py' | awk -F/ -vOFS=/ 'NF-=2' | 
  sed 's#^\(.*/openerp/addons.*\)#aaa%\1#; s#^\(.*/web/addons.*\)#aab%\1#' | 
   sort -u | sed 's/^aa.%//'

Not particularly clever or elegant but this will simply add aaa% to the beginning of lines containing /openerp/addons and aab% to the beginning of lines containing /web/addons. The last sed removes them again after sorting. Assuming you have no files whose name starts with aa.%, that should have the desired result.

Or, you could use a simple perl one-liner that also does the job of sort -u:

find fafa/ | awk -F/ -vOFS=/ 'NF-=2' | 
 perl -ne 's#^(.*/openerp/addons)#aaa%$1#; s#^(.*/web/addons)#aab%$1#; $k{$_}++; 
            END{for (sort keys(%k)){s/^aa.%//; print }}'
share|improve this answer
add comment

As I mentioned in a comment, pipelines are not the way to go; at least not with a tool as simple as grep. I would use a more powerful tool, such as Python or Perl, for this. Here's a Perl filter that might help:

your command | perl -ne '
    if($already_found_lines){
        print # print the current line as is
    } else{
        if   (m{/web/addons}    ) { $web=$_     and $found_web++    }
        elsif(m{/openerp/addons}) { $openerp=$_ and $found_openerp++}
        else                      { push @buffer,$_                 }
        $already_found_lines = ($found_web and $found_openerp);
        if($already_found_lines)  { print "${openerp}$web";print for @buffer}
    }'

This tested correctly with your sample input.

share|improve this answer
    
Thanks, but I do have a code with python, but as mentioned I just wanted it to make bash one liner. So in my case although this is great and works - it's not something I will end up using. –  JackLeo Jan 29 at 14:26
    
@JackLeo Technically, this is a one-liner (whatever that may mean) :). It's not Bash, though, and neither is your solution, which simply uses Bash to invoke external tools. –  Joseph R. Jan 29 at 14:29
    
Well yes you're right. I give you that. Just for something as simple perl seems to be bit of a overkill. I could just pasted the same python code to '' and that would be a one liner as well. –  JackLeo Jan 29 at 14:31
    
@JackLeo I think the "overkillness" of this approach is highly debatable. Would using a simple Python code instead of 4 tool invocations (along with a subshell) be overkill? Also, the higher level code has the advantage of being more readable (in my opinion, at least). –  Joseph R. Jan 29 at 14:34
    
yes I do agree with you, but then why even bother with something passing info to perl/python code while it can get the same info itself. –  JackLeo Jan 29 at 14:39
show 4 more comments

Right now I did it by saving to /tmp/ and then executing grep on it few times:

find "$PWD" -name '__openerp__.py' | awk -F/ -vOFS=/ 'NF-=2' | sort -u > /tmp/openerp_addon_list.txt ; (egrep '/openerp/addons|/web/addons$' /tmp/openerp_addon_list.txt; egrep -v "/openerp/addons|/web/addons|/openerp/test" /tmp/openerp_addon_list.txt)
/home/domas/Sources/openerp/7.0/server/openerp/addons
/home/domas/Sources/openerp/7.0/web/addons
/home/domas/Sources/openerp/7.0/addons
/home/domas/Sources/openerp/7.0/development
/home/domas/Sources/openerp/7.0/external
/home/domas/Sources/openerp/7.0/groups/account-invoice-report
/home/domas/Sources/openerp/7.0/groups/banking-addons
/home/domas/Sources/openerp/7.0/groups/partner-contact-management
/home/domas/Sources/openerp/7.0/groups/sale-reports
/home/domas/Sources/openerp/7.0/groups/webkit-utils
share|improve this answer
    
Did this work for you? Because on my system it only prints two lines given your sample input: <my path> followed by <my path>/server. –  Joseph R. Jan 29 at 14:26
    
yep it works. also I pass output to | tr "\n" "," | sed 's/,$/ /' | tr " " "\n" but this is a bit out of this question boundaries. Maybe my sample is wrong in this case. –  JackLeo Jan 29 at 14:28
    
Edited and added output. –  JackLeo Jan 29 at 14:32
add comment

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.