ruby -e: run Ruby one-liners (with -n, -p, -l, -a for text processing)
- tool
- Ruby
- command
- ruby
- flag
- -e 'code'
- default
- -
ruby -e 'puts 1 + 1' runs the Ruby code given on the command line instead of a script file. Several -e options are joined as separate lines. Combined with -n (loop over input lines), -p (loop and print), -l (chomp line endings and add them back on output) and -a (split each line into $F), Ruby works as a scripting alternative to sed and awk. Libraries are loaded with -r, for example ruby -rjson -e '...'.
One-liners in practice
The example runs the official CRuby 3.4 build for WebAssembly from the ruby.wasm project, as a regular command-line program with Node.js; ruby below is that interpreter:
curl -sSfLO https://github.com/ruby/ruby.wasm/releases/download/2.8.1/ruby-3.4-wasm32-unknown-wasip1-full.tar.gz
echo "ccda86a375a4fe09849846d3b03a370172a4902a0c571087f48457388a2762c7 ruby-3.4-wasm32-unknown-wasip1-full.tar.gz" | sha256sum -c --quiet
tar xzf ruby-3.4-wasm32-unknown-wasip1-full.tar.gz
cat > ruby.mjs <<'JS'
// Minimal "ruby" command: runs the official CRuby 3.4 WASI build with the given arguments
import fs from "node:fs";
import { WASI } from "node:wasi";
const root = "ruby-3.4-wasm32-unknown-wasip1-full/usr";
const wasi = new WASI({ version: "preview1", args: ["ruby", "--disable-gems", ...process.argv.slice(2)], env: {}, preopens: { "/usr": root, ".": "." }, returnOnExit: true });
const mod = await WebAssembly.compile(fs.readFileSync(`${root}/local/bin/ruby`));
process.exitCode = wasi.start(await WebAssembly.instantiate(mod, wasi.getImportObject()));
JS
ruby() { node --no-warnings ruby.mjs "$@"; }
ruby -e 'puts RUBY_VERSION' -e 'puts [3, 1, 2].sort.inspect'
echo "== arguments after --"
ruby -e 'p ARGV' -- --name ruby
echo "== -n: loop, print yourself"
printf 'alpha\nbeta\ngamma\n' | ruby -ne 'puts $_.upcase if $_.start_with?("b", "g")'
echo "== -p: loop and print \$_ (like sed)"
printf 'alpha\nbeta\n' | ruby -pe '$_ = $_.tr("a", "4")'
echo "== -lane: split fields into \$F (like awk)"
printf 'apple 3\npear 5\n' | ruby -lane 'puts "#{$F[0]}: #{$F[1].to_i * 2}"'
echo "== BEGIN/END for totals"
printf '3\n5\n7\n' | ruby -ne 'BEGIN { sum = 0 }; sum += $_.to_i; END { puts "sum = #{sum}" }'
echo "== -rjson"
ruby -rjson -e 'puts JSON.generate({ ok: true, n: [1, 2] })'Output
3.4.1
[1, 2, 3]
== arguments after --
["--name", "ruby"]
== -n: loop, print yourself
BETA
GAMMA
== -p: loop and print $_ (like sed)
4lph4
bet4
== -lane: split fields into $F (like awk)
apple: 6
pear: 10
== BEGIN/END for totals
sum = 15
== -rjson
{"ok":true,"n":[1,2]}Every line of the output comes from the interpreter. Note how -p prints the modified $_ automatically, while -n prints only what you puts; BEGIN and END run once before and after the loop.
Options used with -e
| Option | Effect |
|---|---|
| -e code | Run code; repeat -e for several lines |
| -n | Wrap the code in while gets ... end; the current line is $_ |
| -p | Like -n, and print $_ at the end of each iteration |
| -l | Chomp each input line and set the output record separator to a newline |
| -a | With -n or -p: split $_ into the array $F (on whitespace) |
| -F pattern | Field separator for -a, e.g. -F, for CSV-like data |
| -i[ext] | Edit files in place (with -p), keeping a backup with extension ext |
| -r lib | Require a library before running the code |
| -- args | End of Ruby options; the rest goes to ARGV |
Useful patterns
ruby -pi.bak -e '$_.gsub!("http:", "https:")' links.txt # in-place edit with backup
ruby -F, -lane 'puts $F[2]' data.csv # third column of simple CSV
ruby -rjson -e 'puts JSON.pretty_generate(JSON.parse(STDIN.read))' < data.json
ruby -e 'puts Dir.glob("**/*.rb").size' # count Ruby filesFor real CSV with quoted fields use -rcsv and CSV.parse, because -F, splits on every comma. JSON parsing in scripts is covered in Ruby parse JSON.
Pitfalls
- Quote the code with single quotes in POSIX shells so that
$_and#{...}are not expanded by the shell. $_and$Fexist only with-n/-p; in a plain-ethey arenil.- Without
-l,$_ends with a newline, soputs $_prints it once whileprint $_.upcase + "!"puts the!on the next line. - Warnings are off by default in one-liners too; add
-wto see them (ruby -w).
FAQ
How do I pass arguments to a ruby -e one-liner?
Put them after the code, optionally after --: ruby -e 'p ARGV' -- a b prints ["a", "b"]. Without --, arguments that start with a dash may be read as Ruby options.
What is the difference between -n and -p?
Both wrap the code in a loop over every input line, with the line in $_. -n prints nothing by itself, so you call puts or print; -p prints $_ after each iteration, so changing $_ is enough to transform the text, like sed.
How do I use double quotes in a one-liner on Windows?
cmd.exe does not treat single quotes as quotes. Use double quotes around the code and single-quoted Ruby strings inside it: ruby -e "puts 'hi'". In PowerShell, single quotes around the code work.