내가 하고 있는 일은 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