私は助けが必要です。
説明ではなく名前を持つフォルダがたくさんあります。
各フォルダ内には複数行の「info.txt」ファイルがありますが、それらの2つに興味があります。
artist = Name of the Band
name = Name of the Song
次の構造で各フォルダの名前を変更したいと思います。
Name of the Band - Name of the Song
find、grep、および mv コマンドを組み合わせると問題は解決されると思いますが、正しいスクリプトやコマンドを自分で考えるほど経験が不足しています。
よろしくお願いします!
答え1
これを行うもう1つの方法です(GNUユーティリティを想定)。このテストが良好な場合は、削除してecho
実行してください。
#!/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
ここも悪くありません-T
。デフォルトの動作はmv
、ターゲットが存在しない場合はディレクトリの名前を変更し、存在する場合はディレクトリ全体をターゲットに移動することです。したがって、-T
この期間中に既存のターゲットがある場合は何も移動されません。
私はすべてのディレクトリが同じ深さにあると仮定し、前のレベルで実行する必要があります。
答え2
info.txt
ファイルを何度も読み取る必要がない別の方法は次のとおりです。
#!/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
として保存し、foo.sh
実行可能にした後、次を実行します。
foo.sh path/to/dir1 path/to/dir2 ... path/to/dirN
または端末から直接実行してください。
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
答え3
私が正しく理解したら、これがうまくいくかどうか見てみましょう。
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