raku.gg / one-liners

File Renaming One-Liners

2026-04-07

Batch renaming files is a common task that Raku handles elegantly from the command line. With its powerful regex engine and clean string manipulation, you can rename hundreds of files with a single line.

Basic File Renaming

Rename a single file:
raku -e '"old-name.txt".IO.rename("new-name.txt")'

Batch Rename with a Pattern

Rename all .txt files to .md:
raku -e 'for dir(test => /\.txt$/) -> $f { $f.rename($f.Str.subst(/\.txt$/, ".md")) }'

Lowercase All Filenames

raku -e 'for dir() -> $f { $f.rename($f.Str.lc) if $f.Str ne $f.Str.lc }'

Uppercase All Filenames

raku -e 'for dir() -> $f { $f.rename($f.Str.uc) if $f.Str ne $f.Str.uc }'

Replace Spaces with Hyphens

raku -e 'for dir(test => /\s/) -> $f { $f.rename($f.Str.subst(/\s+/, "-", :g)) }'

Replace Spaces with Underscores

raku -e 'for dir(test => /\s/) -> $f { $f.rename($f.Str.subst(/\s+/, "_", :g)) }'

Add a Prefix

Add "backup_" to all .conf files:
raku -e 'for dir(test => /\.conf$/) -> $f { $f.rename("backup_" ~ $f.Str) }'

Add a Suffix (Before Extension)

Add "v2" before the file extension:
raku -e 'for dir(test => /\.txt$/) -> $f { $f.rename($f.Str.subst(/\.txt$/, "_v2.txt")) }'

Remove a Prefix

Remove "temp
" from filenames:
raku -e 'for dir(test => /^temp_/) -> $f { $f.rename($f.Str.subst(/^temp_/, "")) }'

Sequential Numbering

Rename files to a numbered sequence:
raku -e 'my $n = 1; for dir(test => /\.jpg$/).sort -> $f { $f.rename(sprintf("photo_%03d.jpg", $n++)) }'
This renames anything.jpg to photo_001.jpg, photo_002.jpg, etc.

Date-Based Renaming

Prepend today's date:
raku -e 'my $d = Date.today; for dir(test => /\.log$/) -> $f { $f.rename("{$d}_{$f.Str}") }'

Strip Special Characters

Remove everything except alphanumeric, dots, and hyphens:
raku -e 'for dir() -> $f { my $clean = $f.Str.subst(/<-[a..zA..Z0..9.\-]>/, "_", :g); $f.rename($clean) if $clean ne $f.Str }'

Change Extension Based on Content

Rename .txt files to .csv if they contain commas:
raku -e 'for dir(test => /\.txt$/) -> $f { $f.rename($f.Str.subst(/\.txt$/, ".csv")) if $f.slurp.contains(",") }'

Recursive Renaming

Rename files in subdirectories too:
raku -e 'for "." .IO.dir(:recurse).grep(*.f) -> $f { my $new = $f.Str.subst(/\.jpeg$/, ".jpg"); $f.rename($new) if $new ne $f.Str }'
Note: .dir(:recurse) is not built-in. For recursive traversal, use a helper:
raku -e ' sub walk($dir) { for $dir.dir -> $entry { if $entry.d { walk($entry) } elsif $entry.Str ~~ /\.jpeg$/ { $entry.rename($entry.Str.subst(/\.jpeg$/, ".jpg")); say "Renamed: $entry"; } } } walk(".".IO); '

Dry Run (Preview Changes)

Always preview before renaming. Just replace .rename with a say:
raku -e 'for dir(test => /\.txt$/) -> $f { say "{$f} -> {$f.Str.subst(/\.txt$/, ".md")}" }'
This shows you what would happen without actually renaming anything. Once you are satisfied, change say back to $f.rename(...).

Undo Preparation

Save the mapping before renaming, so you can undo if needed:
raku -e ' my @log; for dir(test => /\.txt$/) -> $f { my $new = $f.Str.subst(/\.txt$/, ".md"); @log.push("{$new}\t{$f}"); $f.rename($new); } "rename-log.txt".IO.spurt(@log.join("\n")); say "Renamed {+@log} files. Undo log saved."; '
To undo:
raku -ne 'my ($new, $old) = .split("\t"); $new.IO.rename($old); say "Restored: $old"' rename-log.txt

Regex-Based Renaming

Use full regex power for complex transformations:
# CamelCase to snake_case raku -e ' for dir(test => /\.rb$/) -> $f { my $new = $f.Str.subst(/ (<[A..Z]>) /, { "_{$0.lc}" }, :g).subst(/^_/, ""); $f.rename($new) if $new ne $f.Str; say "$f -> $new"; } ' # snake_case to CamelCase raku -e ' for dir(test => /\.py$/) -> $f { my $new = $f.Str.subst(/ "_" (.) /, { $0.Str.uc }, :g); say "$f -> $new"; } '

Sanitize Downloaded Filenames

Clean up messy filenames from downloads:
raku -e ' for dir() -> $f { next if $f.d; # Skip directories my $new = $f.Str .subst(/\%20/, " ", :g) # URL-encoded spaces .subst(/\s+/, " ", :g) # Multiple spaces .subst(/^\s|\s$/, "", :g) # Leading/trailing spaces .subst(/<[\[\]\(\)]>/, "", :g); # Brackets if $new ne $f.Str { $f.rename($new); say "Cleaned: {$f.Str} -> $new"; } } '

Tips

File renaming is one of those tasks where Raku's combination of regex power and clean IO operations really pays off. A one-liner that would take a bash script with sed, awk, and a for loop becomes a single readable expression.