"If a task is worth doing more than once, it's worth automating."
-- Rando Lazy Programmer

We were recently contacted with a straight-forward request: replace a portion of all file names in a given directory with an alternate name. For only a few items, one could opt to manually rename each file. At a certain point, though, the time spent carrying out a repetitive task is better invested in figuring out a way to automate it.

In the spirit of automation, then, here's a Bash one-liner :

for file in *; do mv -v "$file" "${file/find_string/replace_string}"; done

which iterates through the contents of a directory, searching for a filename that contains the find_string. Once a match is found, the mv command operates verbosely, replacing the find_string with the replace_string in the filename. This process occurs again until all matching files have been renamed.

If all that is a bit much, take a look at a before:

MACSTER:SF_spdist2_TEST geekberg$ tree
.
|____SF_spDist1_r01_spDist_scanner_20181219T101425.edf
|____SF_spDist1_r01_spDist_scanner_20181219T101425.mat
|____SF_spDist1_r02_spDist_scanner_20181219T102123.edf
|____SF_spDist1_r02_spDist_scanner_20181219T102123.mat
|____SF_spDist1_r03_spDist_scanner_20181219T102638.edf
|____SF_spDist1_r03_spDist_scanner_20181219T102638.mat
|____SF_spDist1_r04_spDist_scanner_20181219T103239.edf
|____SF_spDist1_r04_spDist_scanner_20181219T103239.mat
|____SF_spDist1_r05_spDist_scanner_20181219T103755.edf
|____SF_spDist1_r05_spDist_scanner_20181219T103755.mat
|____SF_spDist1_r06_spDist_scanner_20181219T104404.edf
|____SF_spDist1_r06_spDist_scanner_20181219T104404.mat
|____SF_spDist1_r07_spDist_scanner_20181219T104928.edf
|____SF_spDist1_r07_spDist_scanner_20181219T104928.mat
|____SF_spDist1_r08_spDist_scanner_20181219T105539.edf
|____SF_spDist1_r08_spDist_scanner_20181219T105539.mat
|____SF_spDist1_r09_spDist_scanner_20181219T110057.edf
|____SF_spDist1_r09_spDist_scanner_20181219T110057.mat
|____SF_spDist1_r10_spDist_scanner_20181219T110837.edf
|____SF_spDist1_r10_spDist_scanner_20181219T110837.mat
|____SF_spDist1_r11_spDist_scanner_20181219T111430.edf
|____SF_spDist1_r11_spDist_scanner_20181219T111430.mat
|____SF_spDist1_r12_spDist_scanner_20181219T112040.edf
|____SF_spDist1_r12_spDist_scanner_20181219T112040.mat
|____SF_spDist1_r13_spDist_scanner_20181219T112557.edf
|____SF_spDist1_r13_spDist_scanner_20181219T112557.mat
|____SF_spDist1_r14_spDist_scanner_20181219T113215.edf
|____SF_spDist1_r14_spDist_scanner_20181219T113215.mat
|____SF_spDist1_r15_spDist_scanner_20181219T113746.edf
|____SF_spDist1_r15_spDist_scanner_20181219T113746.mat
|____SF_spDist1_r16_spDist_scanner_20181219T114401.edf
|____SF_spDist1_r16_spDist_scanner_20181219T114401.mat
|____SF_spDist1_r17_spDist_scanner_20181219T114919.edf
|____SF_spDist1_r17_spDist_scanner_20181219T114919.mat
|____SF_spDist1_r18_spDist_scanner_20181219T115530.edf
|____SF_spDist1_r18_spDist_scanner_20181219T115530.mat

and an after:

MACSTER:SF_spdist2_TEST geekberg$ tree
.
|____SF2_r01_spDist_scanner_20181219T101425.edf
|____SF2_r01_spDist_scanner_20181219T101425.mat
|____SF2_r02_spDist_scanner_20181219T102123.edf
|____SF2_r02_spDist_scanner_20181219T102123.mat
|____SF2_r03_spDist_scanner_20181219T102638.edf
|____SF2_r03_spDist_scanner_20181219T102638.mat
|____SF2_r04_spDist_scanner_20181219T103239.edf
|____SF2_r04_spDist_scanner_20181219T103239.mat
|____SF2_r05_spDist_scanner_20181219T103755.edf
|____SF2_r05_spDist_scanner_20181219T103755.mat
|____SF2_r06_spDist_scanner_20181219T104404.edf
|____SF2_r06_spDist_scanner_20181219T104404.mat
|____SF2_r07_spDist_scanner_20181219T104928.edf
|____SF2_r07_spDist_scanner_20181219T104928.mat
|____SF2_r08_spDist_scanner_20181219T105539.edf
|____SF2_r08_spDist_scanner_20181219T105539.mat
|____SF2_r09_spDist_scanner_20181219T110057.edf
|____SF2_r09_spDist_scanner_20181219T110057.mat
|____SF2_r10_spDist_scanner_20181219T110837.edf
|____SF2_r10_spDist_scanner_20181219T110837.mat
|____SF2_r11_spDist_scanner_20181219T111430.edf
|____SF2_r11_spDist_scanner_20181219T111430.mat
|____SF2_r12_spDist_scanner_20181219T112040.edf
|____SF2_r12_spDist_scanner_20181219T112040.mat
|____SF2_r13_spDist_scanner_20181219T112557.edf
|____SF2_r13_spDist_scanner_20181219T112557.mat
|____SF2_r14_spDist_scanner_20181219T113215.edf
|____SF2_r14_spDist_scanner_20181219T113215.mat
|____SF2_r15_spDist_scanner_20181219T113746.edf
|____SF2_r15_spDist_scanner_20181219T113746.mat
|____SF2_r16_spDist_scanner_20181219T114401.edf
|____SF2_r16_spDist_scanner_20181219T114401.mat
|____SF2_r17_spDist_scanner_20181219T114919.edf
|____SF2_r17_spDist_scanner_20181219T114919.mat
|____SF2_r18_spDist_scanner_20181219T115530.edf
|____SF2_r18_spDist_scanner_20181219T115530.mat
.

Here's to hoping this one-liner can save someone a few minutes (or hours!) of work so that they can focus on automating the next task repetitive task.

Cheers.