You are not logged in.

#1 2010-01-21 15:02:25

silvik
Member
From: Bucharest/Romania
Registered: 2006-11-08
Posts: 110

choose a random line from text file in bash

so I've written this script in bash and it works ok on arch. among other things I need to choose a random line from a text file. I used shuf -n1, that does just what I need.

the problem is: when I try to run this script on redhat or other linuxes that used older coreutils shuf isn't available. Also sort -R isn't there.

So what's the simplest portable way to do this?

[I'm not sure that "Newbie corner" is the right place to post this, if not please move it where it belongs. I didn't find a better place]

Offline

#2 2010-01-21 15:06:41

Profjim
Member
From: NYC
Registered: 2008-03-24
Posts: 658

Re: choose a random line from text file in bash

man bash | fgrep -A1 RANDOM

Offline

#3 2010-01-21 15:15:02

rson451
Member
From: Annapolis, MD USA
Registered: 2007-04-15
Posts: 1,233
Website

Re: choose a random line from text file in bash

ugly hack, probably a better way to do this.

FILE='filename.txt'
let "n=${RANDOM}%$(wc -l < $FILE)"
head -n $n $FILE | tail -1

Last edited by rson451 (2010-01-21 20:33:26)


archlinux - please read this and this — twice — then ask questions.
--
http://rsontech.net | http://github.com/rson

Offline

#4 2010-01-21 16:47:03

stefos
Member
From: Netherlands
Registered: 2008-02-14
Posts: 7

Re: choose a random line from text file in bash

Edit:
Never mind, must start reading:D (sort -R not available)

Last edited by stefos (2010-01-21 16:48:18)

Offline

#5 2010-01-21 19:09:10

Profjim
Member
From: NYC
Registered: 2008-03-24
Posts: 658

Re: choose a random line from text file in bash

This also seems to work:

awk -v LINES=$(wc -l $myfile) 'BEGIN {srand(); line=1+int(rand()*LINES) } --line==0 { print; quit }; { next }' < $myfile

Offline

#6 2010-01-21 19:11:39

Ramses de Norre
Member
From: Leuven - Belgium
Registered: 2007-03-27
Posts: 1,289

Re: choose a random line from text file in bash

rson451 wrote:
$(cat $FILE | wc -l)

Useless cat, wc takes arguments, use wc -l $FILE

Offline

#7 2010-01-21 19:14:27

Procyon
Member
Registered: 2008-05-07
Posts: 1,819

Re: choose a random line from text file in bash

Ramses de Norre wrote:
rson451 wrote:
$(cat $FILE | wc -l)

Useless cat, wc takes arguments, use wc -l $FILE

The output won't be the same. But you could use wc -l < $FILE

Offline

#8 2010-01-21 20:31:43

rson451
Member
From: Annapolis, MD USA
Registered: 2007-04-15
Posts: 1,233
Website

Re: choose a random line from text file in bash

Procyon wrote:

The output won't be the same. But you could use wc -l < $FILE

Correct.  Thanks for the redirect thing though, I knew I was missing something and just couldn't grab it.  I had tried $(< $FILE | wc -l) but that fails as well.

Editing my first post to reflect this.

Last edited by rson451 (2010-01-21 20:33:09)


archlinux - please read this and this — twice — then ask questions.
--
http://rsontech.net | http://github.com/rson

Offline

#9 2010-01-22 02:15:38

silvik
Member
From: Bucharest/Romania
Registered: 2006-11-08
Posts: 110

Re: choose a random line from text file in bash

thanks for all suggestions.
I'll probably use rson451's solution because I can understand it. awk is too hardcore for me.

Offline

#10 2010-01-22 11:17:15

Profjim
Member
From: NYC
Registered: 2008-03-24
Posts: 658

Re: choose a random line from text file in bash

Yeah, I agree much cleaner to do it in shell alone, only problem is your distribution won't be flat unless your number of lines is a power of 2. If the number of lines is small, it won't be very far from flat. But to make the problem vivid, suppose you have 21884 lines. Then the first half of them are going to be chosen via the Bash method given twice as often as the second half. If you have 32766 lines, the first line will will be chosen twice as often as all the rest. You can work around that in the shell alone, but it will be more complex. Depending on your intended use, you might just choose to ignore this.

Offline

Board footer

Powered by FluxBB