DEV Community

Sergey Lukin
Sergey Lukin

Posted on

Renaming bulks of files in ZSH

Recently I decided to clean my Netlify functions file names and instead of having <function name>/<function name>.js files having <function name>/index.js ones.

As usual, assuming we're talking about using CLI, I could either complete this task by rapidly running mv x/x x/index.js n times, or I could spend a bit more time fiddling with shell scripting, awk, sed, or any other relevant tool of choice and strengthen my CLI skills. The choice was obvious :)

So assuming following files structure:

- my-func/
  - my-func.js
- my-func2/
  - my-func2.js
  - foobar.js
Enter fullscreen mode Exit fullscreen mode

We'd like to seamlessly transform it into (note that foobar.js should stay untouched):

- my-func/
  - index.js
- my-func2/
  - index.js
  - foobar.js
Enter fullscreen mode Exit fullscreen mode

Here is my final one-liner (ZSH compliant):

for i in ./*/*.js; do if [[ $i:t:r == $(echo $i:h | cut -c3-) ]]; then mv -- "$i" "$i:h/index.js"; fi; done
Enter fullscreen mode Exit fullscreen mode

The interesting parts that required some research (in my case) are the :t :r :h modifiers.

Turns out if you have path in variable, you can extract parts of it by using modifiers:

$myFilePath:t -> prints only the filename with extension
$myFilePath:t:r -> prints only the filename without extension
$myFilePath:h -> prints path to the file
Enter fullscreen mode Exit fullscreen mode

so having this we can easily iterate through the files with for in ./*/*.js and filter out only the files we need by comparing filename ($i:t:r) with the parent directory name ($i:h) and then moving the file to "$i:h/index.js".

Mission accomplished + one more trick learned :)

Happy coding and shell scripting :)

Top comments (0)