Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Join lines that match an string

by ranrodrig (Novice)
on Jul 12, 2010 at 21:27 UTC ( #849112=perlquestion: print w/replies, xml ) Need Help??
ranrodrig has asked for the wisdom of the Perl Monks concerning the following question:

Folks I need your help because I need to join two or more lines in a file, but this have to be done in lines that match "remotely" and until there's "p_agrs" in another line, can you help me with this pls?, also if you can tell me how to do this in one line, that would be great.

TIA for your help

Replies are listed 'Best First'.
Re: Join lines that match an string
by kennethk (Abbot) on Jul 12, 2010 at 21:39 UTC
    Please read How do I post a question effectively?. What have you tried? What didn't work? Why do you want/need a one-liner? What does sample input look like? What does expected output look like? Demonstrated effort is appreciated around here.

    perl -e 'while(<>){chomp; last if /p_agrs/;print if /remotely/}' < input.txt

    might do what you intend. But it might not. If it doesn't meet spec, please post again with greater specificity.

      Sorry for not posting an example, but here it is, so what I need to do is join in one line all the lines that match "remotely" on it (include it) and stop where it's an "p_agrs" match, does this make sense?

      EV = 0x10eb250 (class, event_handle: 3503519, mc_ueid: 1278629168) 20100708 224608.259843 RULES: IMC110203I: #3503519: $EV.m c_host 20100708 224608.260757 RULES: IMC110801I: #3503519: Rule e execution starting with . . . msg='script to be execute remotely: exists("TRUSTEDALARM"); Local Id: Rem_010965WAP_18504'; . . . p_agrs
        "...does this make sense?"

        Better, but without more sample data (including examples of non-desired matches) requested above, not enough.

        You have given an input, but no output. Without that, how can we know if our code outputs to spec? If you run my code above against your input file, do you get what you expect?
Re: Join lines that match an string
by linuxer (Curate) on Jul 12, 2010 at 21:33 UTC

    Can you please provide some sample input data, a definition of your "remotely" criterion to match lines, and a sample output data?

    And what is "p_agrs"?


    1. fixed typo: s/an s/a s/
    2. striked the "p_agrs" question. kennethk's answer clarified that.
Re: Join lines that match an string
by ambrus (Abbot) on Jul 13, 2010 at 09:51 UTC

    If you don't mind words running together where you join the lines, try this command:

    echo -e 'g/\<remotely\>/.,/\<p_args\>/j\nwq' | ed -sl filename

    Example input and output follow.

    If you do mind the words running together, you may need a two-pass solution, eg.

    for t in 's/$/ /' j; do echo -e 'g/\<remotely\>/.,/\<p_args\>/'"$t"'\n +wq' | ed -sl filename

    (Update: added double quotes in the above.)

    (Update: a bit better than the above would be

    g='g/\<remotely\>/.,/\<p_args\>/'; echo -e "${g}s/\$/ /\n${g}j\nwq" | +ed -sl filename


    or some other method, such as

    ex -c $'g/\<remotely\>/.,/\<p_args\>/j\nwq' filename

    Update: uh, I see only now that your terminator is "p_agrs", whereas I thought it was "p_args". I might replace them later in this node, but for now, you'll have to do the replacement yourself.

    Update: did someone mention perl -wpe 'if (/\bremotely\b/.../\bp_args\b/) { chomp }' above? They probably didn't only because they interpreted your question differently.

    See Re^2: Joining two files on common field for a list of nodes where unix textutils is suggested to merge files.

      Kennethk, Linuxer, Ambrus, thanks a lot for your help, Linuxer you got the idea perfectly, many times is very dificult to explain yourself in words and you did it.

      The best solution is what Ambrus wrote

      perl -wpe 'if (/\bremotely\b/.../\bp_args\b/) { chomp }'

      The only problem with this is that it joins the line that is after "p_args" but I can deal with that (perl -e "s/\';host=/\';\host=\n/g" -p data00 > data01. Thanks a lot again for your help, tips and advice

        Right, unlike the other solutions, that one joins the line with the terminator and the next one. You could write

        perl -wpe 'if ((/\bremotely\b/.../\bp_args\b/) !~ /^$|E0/) { chomp }' +a
        but that's a bit ugly, or decide that the flip-flop shortcut isn't appropriate in such case and track the flag by hand, such as
        perl -wpe 'if (($_f ||= /\bremotely\b/) &&= !/\bp_args\b/) { chomp }' +a

        But I still have the feeling I didn't get the whole idea correctly; especially when I see ambrus' solution.

        If you want to keep the linebreak in the "p_agrs" line, then tell perl not to chomp it.


        perl -wpe 'if ( m/\bremotely\b/ ... m/\bp_agrs\b/ ) { chomp unless m/\bp_agrs\b/ }'

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://849112]
Approved by kennethk
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (7)
As of 2018-10-18 11:04 GMT
Find Nodes?
    Voting Booth?
    When I need money for a bigger acquisition, I usually ...

    Results (101 votes). Check out past polls.