This function re-orders the prefices in names of scripts– originally intended to re-order the numbering of scripts developed in the R-Bioconductor-powered data science team's organization style, where script names begin with 01, 02, etc. References to script names within the shell or R scripts are also updated, along with the names of log files they produce.

renumber(
  base_dir,
  pre_before,
  pre_after,
  expect_matches = TRUE,
  recursive_edits = FALSE,
  protect_log_location = TRUE
)

Arguments

base_dir

A character(1) path to a directory containing the scripts to re-order.

pre_before

A character() vector of literal prefices to replace among scripts in base_dir. Regular-expression characters are treated literally.

pre_after

A character() vector of literal replacement prefices among scripts in base_dir.

expect_matches

A logical(1) indicating whether to expect that all prefices in pre_before will match a file in base_dir, throwing an error if not.

recursive_edits

A logical(1) indicating whether to recursively search base_dir for R, shell, and Python scripts and replace any instances of the prefices in pre_before with the corresponding prefices in pre_after. Because of the slight risk where prefices are not uniquely identifiable and unexpected edits take place, the default is FALSE; you must opt in intentionally.

protect_log_location

A logical(1), default TRUE, requiring log files selected through shell scripts to be inside the project returned by here::here(). Logs may be outside base_dir. Set FALSE to permit logs in any directory referenced by shell scripts, without consulting here. This disables only log location checks; collision, link, and recovery checks remain active, and non-log changes must still stay within base_dir.

Details

Non-log changes are confined to the physical directory selected by base_dir. Its symbolic-link aliases resolve to that same scope. Selected symbolic links and hard-linked files are refused; recursive editing does not follow linked directories.

By default, log files selected for renaming must be within the physical project root returned by here::here(), which uses the current R session's project context, not base_dir, to determine the root. If no logs are selected, an outside or missing log directory does not prevent renumbering. The project root and log protection setting are saved in the journal, so recovery uses the original policy even from a different working directory or project context.

Matching uses literal filename prefixes throughout. File stems remove only the final extension, retaining embedded dots; directory stems retain the full basename. A stem is never shortened past a supplied prefix that includes an extension or the whole filename. Distinct stems matched by the same prefix are rejected as ambiguous.

Associated logs must be regular files with the full shell-script stem followed by .txt or .log, optionally with an underscore suffix (the job_loop() convention) or a dot and numeric task ID (the job_single() array convention). Logs sharing only the numeric prefix are not selected. The shell-script stem and replacement are interpreted literally, including any embedded dots or regex characters.

The complete rename plan, including logs, is checked before changes. Hidden files and dangling symbolic links count as occupied destinations. Script edits are prepared in a private recovery directory; logs and data directories are renamed in place, without copying their contents. Only changed scripts have their original bytes backed up. Prepared edits are written into the existing script files, retaining their identity, ownership and ordinary ACLs and extended attributes. Timestamps change, and the operating system may clear special security attributes on modification. Linked script edit targets are refused. An interrupted write can leave partial contents until recovery.

A journal records each move or script edit before execution. Errors and R interrupts trigger rollback in reverse order. If rollback cannot finish, the error reports the recovery directory. After inspecting the affected files, call renumber_recover() with that directory to retry rollback. A leftover recovery directory blocks another call in the same base directory.

Renaming uses base R with destination checks immediately before each move. This is not an atomic transaction: other processes can observe intermediate paths, and a destination created between the check and rename can be replaced. Do not run against files being modified by other processes. Rename recovery refuses occupied destinations or changed objects. Script recovery checks file identity while allowing partial contents from an unfinished write; see renumber_recover() for its conflict checks. Recovery survives ordinary R-session termination, but is not a guarantee against power loss, storage corruption, or arbitrary concurrent changes.

Author

Nicholas J. Eagles

Examples

base_dir <- file.path(tempdir(), "slurmjobs_scripts")
dir.create(base_dir)

#   Create a shell script that submits a corresponding R script
job_single(
    file.path(base_dir, "01_should_be_second.sh"),
    logdir = file.path(base_dir, "logs"), create_logdir = TRUE,
    create_shell = TRUE, command = "Rscript 01_should_be_second.R"
)
#> 2026-11-03 14:21:35.592471 creating the logs directory at:  /tmp/RtmpUNd9rY/slurmjobs_scripts/logs
#> 2026-11-03 14:21:35.593496 creating the shell file /tmp/RtmpUNd9rY/slurmjobs_scripts/01_should_be_second.sh
#> To submit the job use: sbatch /tmp/RtmpUNd9rY/slurmjobs_scripts/01_should_be_second.sh
writeLines("# some code", con = file.path(base_dir, "01_should_be_second.R"))

#   Create an array originally designed to be submitted second
job_loop(
    file.path(base_dir, "02_should_be_first.sh"),
    create_shell = TRUE, logdir = file.path(base_dir, "logs"),
    loops = list(
        gene = c("gene_1", "gene_2"), method = c("method_1", "method_2")
    ) 
)
#> 2026-11-03 14:21:35.595483 creating the logs directory at:  /tmp/RtmpUNd9rY/slurmjobs_scripts/logs
#> 2026-11-03 14:21:35.596775 Creating the shell file 02_should_be_first.sh and corresponding R script 02_should_be_first.R
#> To submit the script pair, use: sbatch /tmp/RtmpUNd9rY/slurmjobs_scripts/02_should_be_first.sh

#   Swap the order of the scripts
# This temporary example is outside the current project.
renumber(base_dir, c("01", "02"), c("02", "01"),
    protect_log_location = FALSE)

#   Check that the scripts have been properly renamed
list.files(base_dir)
#> [1] "01_should_be_first.R"   "01_should_be_first.sh"  "02_should_be_second.R" 
#> [4] "02_should_be_second.sh" "logs"