파일 이름을 얻기 위해 디렉터리 경로 제거

파일 이름을 얻기 위해 디렉터리 경로 제거

내가 하고 있는 일은 LAME를 사용하여 mp3를 변환하는 것입니다. 작동하는 이전 스크립트를 작성했지만 이 기능을 추가하고 싶습니다. 파일을 삭제하는 대신 해당 파일을 사용하여 이미 존재하는 하위 디렉터리가 있는 새 루트 폴더에 저장하세요. 경로는 .

이것은 인터넷에서 얻은 코드이며 스크립트에서 경로를 가져오는 데 사용합니다.

 c=$FILENAME
 xpath=${c%/*} 
 xbase=${c##*/}
 xfext=${xbase##*.}
 xpref=${xbase%.*}
 path=${xpath}
 pref=${xpref}
 ext=${xfext}

그리고 디렉토리 구조를 xpath알려 주세요path/home/user/working-root-directory/band-folder/album-name/

이 기술을 사용하여 밴드 폴더를 별도의 변수에 넣고 앨범 폴더를 별도의 변수에 넣는 스크립트를 어떻게 작성할 수 있습니까?

그런 다음 이를 사용하여 모든 mp3를 밴드 앨범 순서대로 다른 루트 폴더에 저장하는 새 폴더를 만들 수 있습니다. 이렇게 하면 직접 이동할 필요가 없으므로 다음에 스크립트를 실행할 때 그들이 이겼습니다. 더 이상 작업 디렉터리 경로/폴더에 없기 때문에 리샘플링되지 않으며 만일의 경우를 대비해 파일의 백업 복사본을 계속 보관합니다.

답변1

$c다음과 같은 경우 참조할 때파일 이름파일의 전체 경로를 의미한다면 작업은 정말 간단합니다. 이를 수행하는 방법에는 여러 가지가 있습니다.

POSIX 쉘 글로브와 매개변수 확장만을 사용하여 다음을 수행할 수 있습니다.

c='/home/user/working-root-directory/band-folder/album-name/music-file.mp3'
file=${c##*/}
album=${c#*"${c%/*/"$file"}"/}
band=${c#*"${c%/*/"$album"}"/}
band=${band%%/*} album=${album%%/*}

기본적으로 변수의 꼬리 부분에서 문자열을 잘라낸 다음 변수의 머리 부분에서 결과를 잘라내는 방식으로 작동합니다. 마지막 행에서는 꼬리에 있는 원치 않는 잔여물이 제거됩니다. 실제 데이터를 사용하면 이해하기가 더 쉬울 수도 있습니다. 활성화된 쉘에서 위의 코드 조각을 래핑하면 set -x다음 행이 인쇄되는 것을 볼 수 있습니다 stderr.

+ c=/home/user/working-root-directory/band-folder/album-name/music-file.mp3
+ file=music-file.mp3
+ album=album-name/music-file.mp3
+ band=band-folder/album-name/music-file.mp3
+ band=band-folder
+ album=album-name

대안은 /쉘의 내부 필드 구분 기호를 사용하여 경계에서 경로 이름을 분할하는 것입니다.

set -f; IFS=/             #disable globbing so as not to gen more filenames
set -- $c                 #set the shell's arg array to split path
shift "$(($#-3))"         #remove all but relevant fields
band=$1 album=$2 file=$3  #assign values

set -x추가 출력 은 다음과 같습니다 .

+ c=/home/user/working-root-directory/band-folder/album-name/music-file.mp3
+ set -f
+ IFS=/
+ set -- '' home user working-root-directory band-folder album-name music-file.mp3
+ shift 4
+ band=band-folder
+ album=album-name
+ file=music-file.mp3

답변2

나는 zsh이 일을 수행하기 위해 다음과 같은 사람들을 고용할 것입니다:

$ c='/home/user/working-root-directory/band-folder/album-name/filename.mp3'

$ echo $c:h
/home/user/working-root-directory/band-folder/album-name
$ echo $c:h:h
/home/user/working-root-directory/band-folder
$ echo $c:h:h:h
/home/user/working-root-directory

(...)

$ echo $c:t    
filename.mp3
$ echo $c:h:t
album-name
$ echo $c:h:h:t
band-folder

(...)

Bash를 사용하여 삶을 더 어렵게 만들어야 한다면 임시 변수를 사용해야 합니다.

$ c='/home/user/working-root-directory/band-folder/album-name/filename.mp3'

$ x1=${c%/*}
$ echo $x1
/home/user/working-root-directory/band-folder/album-name
$ x2=${x1%/*}
$ echo $x2
/home/user/working-root-directory/band-folder

 (...)

$ y1=${c##*/}
$ echo $y1
filename.mp3
$ y2=${x1##*/}
$ echo $y2
album-name
$ y3=${x2##*/}
$ echo $y3
band-folder

(...)

답변3

이전 솔루션은 나에게 너무 복잡해 보였습니다. 제 생각에는 다음이 가장 간단한 해결책입니다.

Bash에서 파일 이름 문자열의 디렉터리 이름 가져오기

 dirname "$varcontainingfilename"

Bash의 파일 이름 문자열에서 고유한 파일 이름을 얻으려면 다음을 사용하십시오.

 basename "$varcontainingfilename"

이를 바탕으로 원하는 일을 쉽게 할 수 있어야 합니다.

이 쉘 스크립트를 script/a/b/c로 실행하는 예는 다음과 같습니다.

 #!/bin/sh
 set -u
 PATH='/bin:/usr/bin'
 export PATH
 filestring="$1"
 fn=`basename "$filestring"`
 dn=`dirname "$filestring"`
 echo Original File String "$filestring"
 echo Filename is "$fn"
 echo directory is "$dn"
 exit 0

답변4

Zsh는 더 우아한 솔루션입니다하지만 그것이 쉘이 아닌 경우 다음을 사용할 수 있습니다 awk.

 printf "%s\n" "$path"
/home/user/working-root-directory/band-folder/album-name/music-file.mp3

band=$(awk -F/ '{print $(NF-2)}' <(printf "%s" "$path"))
printf "%s\n" "$band"
band-folder

album=$(awk -F/ '{print $(NF-1)}' <(printf "%s" "$path"))
printf "%s\n" "$album"
album-name

file=$(awk -F/ '{print $NF}' <(printf "%s" "$path"))
printf "%s\n" "$file"
music-file.mp3

관련 정보