Skip to content

Commit

Permalink
Clean up file bulk-rename a little
Browse files Browse the repository at this point in the history
- Rename command conventionally
- Optional input especially for globbing
- Add shorthand flags
- Run in parallel
- More tests
  • Loading branch information
texastoland committed Mar 20, 2024
1 parent 7d662ad commit d0e56c4
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 87 deletions.
File renamed without changes.
41 changes: 41 additions & 0 deletions stdlib-candidate/std-rfc/batch-rename.nu
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Rename a batch of files using a closure.
#
# The reason behind this command is quite simple:
# - Sometimes one receives a bunch of files with integer ids: 1, 2, 3, ...
# - These ids come rarely with padding... i.e. 1 instead of 001 when there are 3-digit ids
# - This means that file with id 9 will be sorted way after file with id 1000
#
# This command allows to do such a task!
#
# Examples:
# Rename `.mise.toml` files to `.mise.local.toml` recursively
# > glob **/.mise.toml | batch-rename { str append .local }
#
# Rename files in `/foo` with a name that has an id to have 3 digits with 0-padding
# > batch-rename --dir /foo {
# parse "some_format_{id}"
# | get 0
# | update id { fill --alignment r --character 0 --width 3 }
# | $"some_format_($in.id)"
# }
export def main [
update_stem: closure, # The code to run on the stem of the files: should start with parsing the format and end with reconstructing the same format
--directory (-d): path, # The path where non-hidden files need to be renamed in bulk
--verbose (-v), # Be verbose when moving the files around
]: nothing -> nothing {
let paths = if $directory == null {
$in
} else {
# ls instead of glob for hidden file behavior
ls --full-paths $directory | get name
}
if $paths == null {
error make { msg: 'batch-rename expects input paths or a valid --directory' }
}
$paths | par-each {
let old = $in
let new = $old | path parse | update stem $update_stem | path join
mv --force --verbose=$verbose $old $new
}
ignore
}
35 changes: 0 additions & 35 deletions stdlib-candidate/std-rfc/fs.nu

This file was deleted.

2 changes: 1 addition & 1 deletion stdlib-candidate/std-rfc/mod.nu
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
export module record/
export module str.nu
# commands
export use fs.nu *
export use batch-rename.nu *
export use set-env.nu *
62 changes: 62 additions & 0 deletions stdlib-candidate/tests/batch-rename.nu
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use std assert
use ../std-rfc 'batch-rename'

const fixture = [
.gitignore
Cargo.toml
LICENSE
README.md
src
test.nu
]

export def 'test batch-rename --directory' [] {
test batch-rename {
batch-rename --directory $in { '_' + $in }
} --expects [
.gitignore # hidden by default
_Cargo.toml
_LICENSE
_README.md
_src
_test.nu
]
}

export def 'test batch-rename where' [] {
test batch-rename {
glob ($in | path join *.*) | batch-rename { '_' + $in }
} --expects [
LICENSE # skip
_.gitignore
_Cargo.toml
_README.md
_test.nu
src # skip
]
}

export def 'test batch-rename missing' [] {
assert error {
test batch-rename { ignore | batch-rename { '_' + $in } }
}
}

def 'test batch-rename' [
command: closure
--expects: list<string>
] {
let test_dir = $nu.temp-path | path join (random uuid)
def actual-files [] {
ls --all --short-names $test_dir | get name | sort
}
# before
mkdir $test_dir
$fixture | each { |name| touch ($test_dir | path join $name) }
assert equal $fixture (actual-files)
# test
$test_dir | do $command
assert equal $expects (actual-files)
# after
rm --recursive --force $test_dir
}
50 changes: 0 additions & 50 deletions stdlib-candidate/tests/fs.nu

This file was deleted.

2 changes: 1 addition & 1 deletion stdlib-candidate/tests/mod.nu
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export module fs.nu
export module batch-rename.nu
export module record.nu
export module str.nu

0 comments on commit d0e56c4

Please sign in to comment.