help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] multiline random paste or how to properly use (named) st


From: Greg Wooledge
Subject: Re: [Help-bash] multiline random paste or how to properly use (named) streams
Date: Tue, 13 Mar 2018 12:57:45 -0400
User-agent: NeoMutt/20170113 (1.7.2)

On Tue, Mar 13, 2018 at 04:49:47PM +0100, Garreau, Alexandre wrote:
> Recently a friend of mine asked me if I would have a right away solution
> to interleaves line of a file foo and a file bar (m3u files actually),

Music play lists.  Good.  Having the context is helpful.  An m3u file
has one filename per line (either CR-LF or newline terminated), as I
understand it.  No blank lines, no markup or groupings or comments or
anything else.

> in a way that each (at random) 1 to 5 lines of “foo” would be surrounded
> by (at random) 2 to 4 (preferably but not necessarily) random unique
> (not appearing several times in total) lines of “bar”

When you say "surrounded by", do you actually mean "followed by"?

So, as I understand it, the problem is as follows:

1) We have two text files containing multiple lines.  There is no semantic
   meaning to the lines (they are filenames, but we're not going to be
   opening or statting the files).  They are of roughly equal sizes.

2) The first file is to be used in sequential order.  The second file is
   to be randomly shuffled.
   
   2a) A recent GNU coreutils is available for the shuffling.

3) A single output file is to be produced, containing lines from both
   input files, following a sequence of steps.  At each step, read 1-5
   lines from the first file, and write them to the output.  Then read
   2-4 lines from the (shuffled) second file, and write those to the
   output.

If this is the full problem spec, then here's one approach:


#!/bin/bash

exec 3< file1
exec 4< <(shuf file2)

while true; do
    # Read 1-5 lines from first file.
    n=$((1 + RANDOM%5))
    for ((i=1; i<=n; i++)); do
        IFS= read -r line <&3 || break
        printf %s\\n "$line"
    done

    # Read 2-4 lines from second file.
    n=$((2 + RANDOM%3))
    for ((i=1; i<=n; i++)); do
        IFS= read -r line <&4 || break
        printf %s\\n "$line"
    done
done

exec 3<&- 4<&-


This terminates as soon as it reaches EOF in either file.  This may
cause some lines from the *other* file (whichever one didn't hit EOF)
to be unused.  If that's a problem, well, you can fix it. ;-)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]