Re: printing words without newlines?

Kaz Kylheku <[email protected]> Mon, 13 May 2024 16:49:59 -0000 (UTC)
Newsgroups alt.comp.lang.awk,comp.lang.awk
Organization A noiseless patient Spider
Message-ID <[email protected]>
On 2024-05-12, Kenny McCormack <[email protected]> wrote:
> In article <[email protected]>,
> Bruce Horrocks  <[email protected]> wrote:
> ...
>>You need to set ORS in the BEGIN { } section (or on the command line).
>
> This is demonstrably false.  You can set ORS whenever/wherever you want.
> Whatever value it has when a plain "print" statement is executed, is what
> will be used.  You are probably about thinking about the various variables
> that affect input parsing. These variables clearly must be set prior to the
> reading of the input, which usually means they need to be set in BEGIN (or
> via something like -F or -v on the command line).
>
> One of my favorite idioms (and one that might actually be useful to OP) is:
>
> # Print every 3 input lines as a single output line
> # Yes, this single line is the whole program!
> ORS = NR % 3 ? " " : "\n"
>
>>See 
>><https://www.gnu.org/software/gawk/manual/html_node/Output-Separators.html> 
>>for an example - just replace the "\n\n" in the example with " " to see 
>>the effect you are looking for.
>
> Of course, the whole point of this thread is that none of us has any idea
> what OP is talking about or what his actual problem is.  We can only guess...

The problem seems to be that there is a file of words preceded by
unique integer ranks which indicate the order. They are to be reproduced
in rank order, on one line.

s is the TXR Lisp interactive listener of TXR 294.
Quit with :quit or Ctrl-D on an empty line. Ctrl-X ? for cheatsheet.
Self-assembly keeps TXR costs low; but ask about our installation service!
1> (flow "data.txt"
      file-get-lines
      (mapcar (do match `@a @b` @1 (vec (pred (toint a)) b)))
      transpose
      (select (second @1) (first @1))
      (join-with " ")
      put-line)
all your base are belong to us

We can insert prints into the pipeline to see the transformations:

2> (flow "data.txt"
      prinl
      file-get-lines
      prinl
      (mapcar (do match `@a @b` @1 (vec (pred (toint a)) b)))
      prinl
      transpose
      prinl
      (select (second @1) (first @1))
      prinl
      (join-with " ")
      prinl
      put-line)
"data.txt"
("2 your" "1 all" "3 base" "5 belong" "4 are" "7 us" "6 to")
(#(1 "your") #(0 "all") #(2 "base") #(4 "belong") #(3 "are") #(6 "us")
 #(5 "to"))
#(#(1 0 2 4 3 6 5) #("your" "all" "base" "belong" "are" "us" "to"))
#("all" "your" "base" "are" "belong" "to" "us")
"all your base are belong to us"
all your base are belong to us
t

That is tedious; say, why not make a macro dflow (debug flow) which inserts
those prinl's for us?

3> (defmacro dflow (. args)
     ^(flow ,*(interpose 'prinl args)))
dflow

Sanity check: is it inserting prinls?

4> (macroexpand-1 '(dflow a b c d))
(flow a prinl
  b prinl c prinl
  d)

Use dflow:

5> (dflow "data.txt"
      file-get-lines
      (mapcar (do match `@a @b` @1 (vec (pred (toint a)) b)))
      transpose
      (select (second @1) (first @1))
      (join-with " ")
      put-line)
"data.txt"
("2 your" "1 all" "3 base" "5 belong" "4 are" "7 us" "6 to")
(#(1 "your") #(0 "all") #(2 "base") #(4 "belong") #(3 "are") #(6 "us")
 #(5 "to"))
#(#(1 0 2 4 3 6 5) #("your" "all" "base" "belong" "are" "us" "to"))
#("all" "your" "base" "are" "belong" "to" "us")
"all your base are belong to us"
all your base are belong to us
t

After file-get-lines we have a list of strings like "2 your".

We map those through an anonymous function which matches the
string pattern `@a @b` to capture the space-separated text pieces.
A is converted to integer and mapped to its predecessor
(because we want to use it as an index, and indexing is zero based).
We map each string to a two element vector consisting of the
zero-based index as an integer type, and a string, so now we have:

(#(1 "your") #(0 "all") ...)

#(a b c) is a vector notation.

Then we want to transpose rows to columns to get the integer
column as a vector, and the values as a vector.

#(#(1 0 2 4 3 6 5) #("your" "all" "base" "belong" "are" "us" "to"))

Now we use the built-in function select which selects elements out
of a sequence, based on indices supplied in another sequence.

Now we have the vector of words in the right order; we just
join with a space.