同じディレクトリにあるフォルダと一致するようにtxtファイルの名前を一括変更しますか?

同じディレクトリにあるフォルダと一致するようにtxtファイルの名前を一括変更しますか?

~/Desktop/a/ には、次の形式のフォルダー (名前にスペースを含む) と txt ファイルがあります。

100 description of project A
100_notes.txt
200 description of project B
200_notes.txt

私が欲しいもの:

100 description of project A
100 description of project A.txt
200 description of project B
200 description of project B.txt

これまでのスクリプトは次のとおりです。

#!/bin/bash
cd ~/Desktop/a/
for i in *; do
  mv "$i/${f%.txt}" "$i.txt";
done

テストファイルを使用しようとしていますが、フォルダ名が.txt拡張子を持つように変更されますが、これは私が望むものではありません。

答え1

#!/bin/sh

for notes in ./???_notes.txt
do
    if [ ! -f "$notes" ]; then
        continue
    fi

    num=${notes%_notes.txt}

    set -- "$num "*/
    if [ "$#" -gt 1 ]; then
        echo 'More than one directory found:' >&2
        printf '\t%s\n' "$@" >&2
        printf 'Skipping %s...\n' "$notes" >&2
        continue
    elif [ ! -d "$1" ]; then
        printf 'No directory matching "%s" found\n' "$num */" >&2
        printf 'Skipping %s...\n' "$notes" >&2
        continue
    fi

    printf 'Would rename "%s" into "%s"\n' "$notes" "${1%/}.txt"
    # mv -i "$notes" "${1%/}.txt"
done

NNN_notes.txtこのスクリプトは現在のディレクトリのすべてのファイルを繰り返します。各ファイルに対して数字NNN(3桁の文字列可能)が抽出され、すべてのファイルを検出するために使用されます。目次呼び出しNNNの後にはスペースと文字列が続きます。

単一のディレクトリが見つかると、それに応じてファイル名が変更されます(実際の名前の変更は安全のためにコメントアウトされます)。複数のディレクトリが見つかった場合、またはディレクトリが見つからない場合は、それを示すメッセージが表示されます。

パラメータ置換は${variable%string}値の末尾から文字列を削除します。このコマンドは、このスクリプトで使用されている場合、位置パラメータなどを指定されたファイル名のワイルドカードパターンと一致するものに設定します(このスクリプトでは、パターンがディレクトリと正確に一致するようにしたい)。値はそのような位置パラメータの数です。string$variableset$1$2$3$#

私がこのスクリプトを書いた方法はとによってbash実行できます/bin/sh。 「bashism」を使用しません。

バージョンのみbash

#!/bin/bash

shopt -s nullglob

for notes in ./???_notes.txt
do
    num=${notes%_notes.txt}

    dirs=( "$num "*/ )
    if [ "${#dirs[@]}" -gt 1 ]; then
        echo 'More than one directory found:' >&2
        printf '\t%s\n' "${dirs[@]}" >&2
        printf 'Skipping %s...\n' "$notes" >&2
        continue
    elif [ "${#dirs[@]}" -eq 0 ]; then
        printf 'No directory matching "%s" found\n' "$num */" >&2
        printf 'Skipping %s...\n' "$notes" >&2
        continue
    fi

    printf 'Would rename "%s" into "%s"\n' "$notes" "${dirs[0]%/}.txt"
    # mv -i "$notes" "${dirs[0]%/}.txt"
done

ここで最大の違いは、名前付き配列を使用してパターンのdirs可能な拡張を維持し、"$num "*/シェルオプションを使用してnullglob一致しないファイル名パターンを何も拡張しないことです。

関連情報