1

I would need some help.

I have a bunch of folders, with non-descriptive names.

Inside each folder, there is a "info.txt" file with several lines, but I'm interested in two of them:

artist = Name of the Band
name = Name of the Song

I would like to rename each folder with the structure:

Name of the Band - Name of the Song

I guess some combination of the find, grep and mv commands would do the trick, but I have not enough experience to come up with the correct script or command on my own.

thanks in advance!

3 Answers 3

1

Another way to do this (assuming GNU utilities). If this test is good, remove echo to run it.

#!/bin/sh -
for f in */info.txt; do
    a="$(grep -Pom1 -- "(?<=^artist = ).*" "$f")"
    n="$(grep -Pom1 -- "(?<=^name = ).*" "$f")"
    echo mv -T -- "${f%/*}" "$a - $n"
done

Also -T is good here. The default behaviour of mv is to rename the directory if the target does not exist and to move the whole directory inside the target if the target exists. So with -T in case of any existing target during this, nothing will be moved.

I have assumed all the directories are on the same depth and you have to run it from one level up.

0

Here's another way, that doesn't require reading the info.txt file multiple times:

#!/usr/bin/env bash

## Give a list of target folders in the command line
for dir in "$@"; do
  . <(awk -F'=' '$1=="artist" || $1=="name"{
                      sub(/^ /,"",$2); 
                      print $1"=\""$2"\""
                 }' "$dir/info.txt")
  mv -- "$dir" "$artist - $name"
done

Save that as foo.sh, make it executable, and run:

foo.sh path/to/dir1 path/to/dir2 ... path/to/dirN

Or just run it in the terminal directly:

for dir in path/to/dir1 path/to/dir2 ... path/to/dirN; do
  . <(awk -F'=' '$1=="artist" || $1=="name"{
                      sub(/^ /,"",$2); 
                      print $1"=\""$2"\""
                 }' "$dir/info.txt")
  mv -- "$dir" "$artist - $name"
done
0

Let's see if this works for you if I understand you correctly:

for i in /path/to/your/dirs/*/info.txt; do
  band=$(awk -F'= ' '/^artist/ { print $2 }' "$i")
  
  song=$(awk -F'= ' '/^name/ { print $2 }' "$i")
  
  folder_name="$band - $song"  

  mv "$(dirname "$i")" "$folder_name"
done
2
  • 2
    Note that it assumes the names of the artists and songs don't contain = characters and that artist and name don't occur anywhere in the other lines. With GNU grep, you could do: band=$(grep -Pom1 '^\s*artist\s*=\s*\K.*' < "$i") instead. Commented Oct 16, 2020 at 8:17
  • @StéphaneChazelas Fair points. Added ^ for precision, and after work a I will see if I can fix the "=" problem. Not an excuse for poor code but an equal sign in a name of a band/song is the rarest thing I've seen :) Commented Oct 16, 2020 at 11:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .