Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello Friends,
I have a large file that contains several hundred lines like below:
Xmodels node1 node2 D G S S Al=1 X=2 V=2e-6 =? bitval=1 model=bitval20 color=30 =? coordinates x-val=20 y-val=30 targetDestroyed=yes =? missionstatus=completed perimeterSecured=yes =? repeatMission=false newMission=yes =? ordinance=34!44 countrycode=red Xmodels node1020 node4300 D G S S Al=12 X=222 V=23e-6 =? bitval=0101 model=bitval28 color=101AFFFB =? coordinates x-val=2370 y-val=390 targetDestroyed=no =? missionstatus=abandoned perimeterSecured=indeterminate =? repeatMission=false newMission=InexploreStage =? ordinance=NULL countrycode=purple Mmodel 300 90 axis-x axis-y 10110001 + firemethod=automatic burstmode=yes + modeltype=gatlin revolve=true + mmodellinespeed=3000fps targacquire=manual manned=optional Mmodel 330 190 axis-x axis-y 1A11FFF1 + firemethod=automatic burstmode=yes + modeltype=FOEAWE revolve=true + mmodellinespeed=3000fps targacquire=automatic + manned=optional + roundspersecond=13000/s

How can we create an output file that contains the above lines re-arranged as below?
Xmodels node1 node2 D G S S Al=1 X=2 V=2e-6 =? bitval=1 model=bitval20 + color=30 =? coordinates x-val=20 y-val=30 targetDestroyed=yes =? mis +sionstatus=completed perimeterSecured=yes =? repeatMission=false newM +ission=yes =? ordinance=34!44 countrycode=red Xmodels node1020 node4300 D G S S Al=12 X=222 V=23e-6 =? bitval=0101 m +odel=bitval28 color=101AFFFB =? coordinates x-val=2370 y-val=390 targ +etDestroyed=no =? missionstatus=abandoned perimeterSecured=indetermin +ate =? repeatMission=false newMission=InexploreStage ordinance=NULL +countrycode=purple Mmodel 300 90 axis-x axis-y 10110001 + firemethod=automatic burstmode= +yes + modeltype=gatlin revolve=true + mmodellinespeed=3000fps targacq +uire=manual manned=optional Mmodel 330 190 axis-x axis-y 1A11FFF1 + firemethod=automatic burstmode +=yes + modeltype=FOEAWE revolve=true + mmodellinespeed=3000fps targac +quire=automatic+ manned=optional + roundspersecond=13000/s

Sorry, new to Perl. Thanks in advance for your help.

Replies are listed 'Best First'.
Re: Combining multiple lines into one line
by BrowserUk (Patriarch) on Apr 29, 2011 at 00:41 UTC

    Assuming that there is a missing blank line between your first two records, then a one-liner with 'paragraph mode' will do the trick:

    perl -e"BEGIN{$/=''}" -ple"tr[\n][]d" input.file > output.file

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Combining multiple lines into one line
by wind (Priest) on Apr 29, 2011 at 00:42 UTC

    It looks like your data is delimited by double returns. However, your example breaks that pattern for the first record.

    Therefore the below solution assumes that paragraph mode wouldn't work:

    my $data = do {local $/; <DATA>}; $data =~ s/\n(?=\=\?|\+)//g; print $data; __DATA__ Xmodels node1 node2 D G S S Al=1 X=2 V=2e-6 =? bitval=1 model=bitval20 color=30 =? coordinates x-val=20 y-val=30 targetDestroyed=yes =? missionstatus=completed perimeterSecured=yes =? repeatMission=false newMission=yes =? ordinance=34!44 countrycode=red Xmodels node1020 node4300 D G S S Al=12 X=222 V=23e-6 =? bitval=0101 model=bitval28 color=101AFFFB =? coordinates x-val=2370 y-val=390 targetDestroyed=no =? missionstatus=abandoned perimeterSecured=indeterminate =? repeatMission=false newMission=InexploreStage =? ordinance=NULL countrycode=purple Mmodel 300 90 axis-x axis-y 10110001 + firemethod=automatic burstmode=yes + modeltype=gatlin revolve=true + mmodellinespeed=3000fps targacquire=manual manned=optional Mmodel 330 190 axis-x axis-y 1A11FFF1 + firemethod=automatic burstmode=yes + modeltype=FOEAWE revolve=true + mmodellinespeed=3000fps targacquire=automatic + manned=optional + roundspersecond=13000/s
Re: Combining multiple lines into one line
by toolic (Bishop) on Apr 29, 2011 at 00:53 UTC
    Replace all newlines as you read in each line with a single space, prepend your model lines with a couple newlines, then print:
    use warnings; use strict; while (<DATA>) { s/\n/ /; s/^(\wmodel)/\n\n$1/; print; } __DATA__ Xmodels node1 node2 D G S S Al=1 X=2 V=2e-6 =? bitval=1 model=bitval20 color=30 =? coordinates x-val=20 y-val=30 targetDestroyed=yes =? missionstatus=completed perimeterSecured=yes =? repeatMission=false newMission=yes =? ordinance=34!44 countrycode=red Xmodels node1020 node4300 D G S S Al=12 X=222 V=23e-6 =? bitval=0101 model=bitval28 color=101AFFFB =? coordinates x-val=2370 y-val=390 targetDestroyed=no =? missionstatus=abandoned perimeterSecured=indeterminate =? repeatMission=false newMission=InexploreStage =? ordinance=NULL countrycode=purple Mmodel 300 90 axis-x axis-y 10110001 + firemethod=automatic burstmode=yes + modeltype=gatlin revolve=true + mmodellinespeed=3000fps targacquire=manual manned=optional Mmodel 330 190 axis-x axis-y 1A11FFF1 + firemethod=automatic burstmode=yes + modeltype=FOEAWE revolve=true + mmodellinespeed=3000fps targacquire=automatic + manned=optional + roundspersecond=13000/s
    perlintro
Re: Combining multiple lines into one line
by locked_user sundialsvc4 (Abbot) on Apr 29, 2011 at 02:09 UTC

    When I consider problems like the one you describe, I freely admit that I’m heavily influenced by a tool ... awk ... that is known to be one of the (so to speak...) “inspirations for” Perl.   This tool (IMHO) encourages you to consider a file “line-type by line-type.”   It is a very-useful, generalized approach to problems of this type that generally consists of three questions:

    1. What type of line (record...) am I right-now looking at?
    2. Now that I know this ... what should I do with this type of line?
    3. Now that I’ve done this ... “am I finished yet?”   (And if so, what should I do?)

    Bear with me, now...   You might, for example, decide that the “types of lines” might be:

    • (First line... beginning of file...)
    • Lines that begin with XModel
    • Lines that begin with model
    • Lines that begin with =?\b
    • Blank lines
    • (Last line... end of file...)

    Please let me refer you to man awk from this point forward.   awk is, in fact, a generalized tool to address this very type of problem, and it is one of the acknowledged inspirations for Perl.   No matter what tool you use to solve your problem, the approach that is encouraged by awk is (I think...) very useful food for thought.