동일한 디렉터리에 있는 폴더와 일치하도록 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일치하지 않는 파일 이름 패턴을 아무것도 확장하지 않는다는 것입니다.

관련 정보