one-liners intermediate

How to shuffle lines randomly with perl one-liner?

Question

How to shuffle lines randomly with perl one-liner?

To shuffle lines randomly in Perl with a one-liner, the key is to read all lines into an array first, then perform an in-memory Fisher-Yates shuffle. This algorithm swaps elements from the end to the beginning, picking a random index each time. A common error when running inline Perl is to include the literal command perl -e inside your code block, causing syntax errors. The one-liner itself should start after the perl -e part; the shell command invokes Perl with the given code.

Fixed and Runnable Perl One-Liner to Shuffle Lines

@lines = <>;
for ($i = $#lines; $i > 0; $i--) {
    $j = int rand($i + 1);
    @lines[$i, $j] = @lines[$j, $i];
}
print @lines;

You can run this code as a one-liner from the shell like this (without embedding perl -e inside):

  • perl -e '@lines = <>; for ($i = $#lines; $i > 0; $i--) { $j = int rand($i+1); @lines[$i,$j] = @lines[$j,$i]; } print @lines;' filename.txt
  • cat filename.txt | perl -e '@lines = <>; for ($i = $#lines; $i > 0; $i--) { $j = int rand($i+1); @lines[$i,$j] = @lines[$j,$i]; } print @lines;'

Explanation

  • @lines = <>; reads all input lines (including trailing newlines) from standard input or files.
  • $#lines is the last index of the array @lines.
  • The loop counts backward from the last index to 1, ensuring every element has a chance to be swapped.
  • int rand($i+1) generates a random index from 0 to $i, inclusive.
  • Swapping uses array slices @lines[$i,$j] to exchange elements efficiently.
  • print @lines; outputs all shuffled lines, preserving newlines.

Common Pitfalls

  • Do not include perl -e inside your Perl code block; this is part of the shell command.
  • One-liners inside single quotes may need escaping if you add semicolons or special characters.
  • Using -n or -p modifiers won't work here because lines are processed one at a time rather than accumulating all lines.
  • Ensure your input file is small enough to fit into memory.
  • No need to explicitly seed rand() in Perl 5.004+ because it is auto-seeded.

Summary

This approach leverages Perl's flexible syntax and built-in array features to implement an efficient Fisher-Yates shuffle in a concise and idiomatic one-liner. Using core Perl functions only, it adapts easily for files or piped input and demonstrates Perl's "There's More Than One Way To Do It" philosophy at its finest.

Verified Code

Executed in a sandbox to capture real output. • v5.34.1 • 70ms

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
(empty)
STDERR
(empty)

Was this helpful?

Related Questions