< up >
2023-11-15

How to rename files without specifying the path twice

How to avoid mv /this/is/a/long/path/to/my/guinea/pig/trfel.pig /this/is/a/long/path/to/my/guinea/pig/trueffel.pig and just do something like <cmd> /this/is/a/long/path/to/my/guinea/pig/trfel.file trueffel.pig?

Maybe I’m totally off today1, or this naive question hasn’t a navie answer. Anyway, I couldn’t come up with a straight-forward solution within my bash2.

I’d like to have an easy memorable solution without pattern matching or syntax.

DIY

I came up with my own renaming tool, just wrapping the os.Rename call with the right parameters:

package main

import (
	"fmt"
	"os"
	"path/filepath"
)

func main() {
	if len(os.Args) != 3 {
		fmt.Println("usage: r <path> <new_filename>")
		return
	}

	newPath := filepath.Join(filepath.Dir(os.Args[1]), os.Args[2])

	if err := os.Rename(os.Args[1], newPath); err != nil {
		fmt.Printf("error renaming %s to %s: %s\n", os.Args[1], newPath, err)
		return
	}

	fmt.Printf("%s -> %s\n", os.Args[1], newPath)
}

Which works like:

> r /home/jane/dev/r/main.c main.go
/home/jane/dev/r/main.c -> /home/jane/dev/r/main.go

SO solutions

I found this SO Post afterwards, but wasn’t satisfied. The acknowledged answer using mv and brace-expansion only works if the suffix need to be renamed. The next answer with rename is imo not intuitive. I just want to rename without any generic/pattern/expansion stuff.


  1. Like my guinea pig Trüffel (see feature image) who’s waiting for the next kohlrabi feeding.
  2. Please prove me wrong and show me an easy way feedback@evilcookie.de