0

I frequently find myself renaming .flac-files in order to remove abundant information. I write a loop where I edit filenames by manually writing out the part that I want removed. E.g. I have a folder full of files like this:

$ ls -l
-rw-r--r-- 1 me me 315416376 Jan  6  2021 'Föllakzoid - 01 - I.flac'
-rw-r--r-- 1 me me 250380814 Jan  6  2021 'Föllakzoid - 02 - II.flac'
-rw-r--r-- 1 me me 336071410 Jan  6  2021 'Föllakzoid - 03 - III.flac'
-rw-r--r-- 1 me me 258787367 Jan  6  2021 'Föllakzoid - 04 - IIII.flac'

With the desired output being:

$ ls -l
-rw-r--r-- 1 me me 315416376 Jan  6  2021 '01 - I.flac'
-rw-r--r-- 1 me me 250380814 Jan  6  2021 '02 - II.flac'
-rw-r--r-- 1 me me 336071410 Jan  6  2021 '03 - III.flac'
-rw-r--r-- 1 me me 258787367 Jan  6  2021 '04 - IIII.flac'

Here I want to remove the "Föllakzoid - "-part from all of the files (as I that information is conveyed through a folder structure further up). Instead of manually typing

$ for file in *.flac; do a=`echo "$file" | sed 's/Föllakzoid - //'`; mv "$file" "$a"; done

I'd rather find the "Föllakzoid -"-part automatically and remove it from all files. Than I could abstract it into a script and re-use all the time (Thereby improving my bash-skills along the way).

I found some similar questions here (on stackoverflow) but they deal with lists of items where order is not important. In my case I want to search for equal substrings in multiple longer strings: I am looking for a function that returns the intersection of multiple strings. So the order of letters is important (as opposed to other questions about list-intersections.

Is there a simple tool in the riches of the depths of /usr/bin ?

exocortex
  • 375
  • 2
  • 9
  • 1
    Please add your desired output for that sample input to your question (no comment). – Cyrus Jun 23 '22 at 20:57
  • 1
    not sure about such a tool, but seems like the "longest common prefix" is what you want, if it is common for **all** files inside a dir – vladtkachuk Jun 23 '22 at 21:04
  • Put your for loop in a file and execute it with `bash /path/to/your script` – Cyrus Jun 23 '22 at 21:30
  • Simpler than infer the common part, you may get it from the folder name further up. – mouviciel Jun 24 '22 at 10:06
  • If you want to remove info implied by the file structure, perhaps consider showing us that file structure, not just the file names. (if you want to remove common parts of the file name, the leading 0 is going to be remove too, unless you get files with a 10, etc.) – MatBailie Dec 04 '22 at 17:02

2 Answers2

1

You might want to have a look at rename. It's not a standard utility but it's widely available on Linux.

That said, you can also write your own function/script that works with literal globs (you'll loose the speed of remane though):

The code was made in a jiffy so there're border cases that need to be addressed (it's not so easy to write something generic, flexible and robust at the same time)

#!/bin/bash

ren() {
    (( $# > 2 )) || return 1
    local fpath
    for fpath in "${@:3}"
    do
        [[ $fpath =~ ^(.*/)?(.+)$ ]] || continue
        mv "$fpath" "${BASH_REMATCH[1]}${BASH_REMATCH[2]/$1/$2}"
    done
}

note: Here I used the bash parameter expansion ${var/glob/repl} that replaces the first occurrence of glob with repl, but there exists a few others that might prove useful; for example there's a ${var#glob} that strips the shortest left-side match of glob from $var (i.e. if $var expands to Föllakzoid - 01 - I.flac then ${var#* - } will expand to 01 - I.flac).

Then you can use the function like this:

ren 'w*d' 'guys' /path/file_hello_world.txt /passwd/www_domains.txt

And that'll execute the commands:

mv /path/file_hello_world.txt /path/file_hello_guys.txt
mv /passwd/www_domains.txt /passwd/guysomains.txt
Fravadona
  • 13,917
  • 1
  • 23
  • 35
0

The renameutils package's qmv command with a file glob will drop you into an editor to make the pattern change you want and will make the change you requested on exit. Good for the case where the use cases aren't 100% consistent and require a lot of special casing. May not be the best option, but still a good tool to have in one's grasp.

Bruce Edge
  • 1,975
  • 1
  • 23
  • 31