programing

Bash 스크립트의 경로에서 파일 이름만 가져옵니다.

telecom 2023. 5. 5. 08:36
반응형

Bash 스크립트의 경로에서 파일 이름만 가져옵니다.

확장자가 없고 경로가 없는 파일 이름만 어떻게 얻을 수 있습니까?

다음은 확장을 제공하지 않지만 경로가 연결되어 있습니다.

source_file_filename_no_ext=${source_file%.*}

UNIX와 유사한 많은 운영 체제는basename매우 유사한 목적을 위한 실행 파일(및dirname경로):

pax> full_name=/tmp/file.txt
pax> base_name=$(basename ${full_name})
pax> echo ${base_name}
file.txt

안타깝게도 확장자를 포함한 파일 이름만 제공되므로 이 파일도 제거할 수 있는 방법을 찾아야 합니다.

어쨌든 그렇게 해야 한다는 것을 감안할 때, 경로와 확장을 제거할 수 있는 방법을 찾는 것이 좋습니다.

그렇게 하는 한 가지 방법(그리고 이것은bash- 다른 실행 파일이 필요 없는 유일한 솔루션):

pax> full_name=/tmp/xx/file.tar.gz
pax> xpath=${full_name%/*} 
pax> xbase=${full_name##*/}
pax> xfext=${xbase##*.}
pax> xpref=${xbase%.*}
pax> echo "path='${xpath}', pref='${xpref}', ext='${xfext}'"

path='/tmp/xx', pref='file.tar', ext='gz'

그 작은 조각 세트들은xpath(파일 경로),xpref(파일 접두사, 구체적으로 요청한 내용) 및xfext(파일 확장명).

basename그리고.dirname솔루션이 더 편리합니다.대체 명령은 다음과 같습니다.

FILE_PATH="/opt/datastores/sda2/test.old.img"
echo "$FILE_PATH" | sed "s/.*\///"

반환됩니다.test.old.img맘에 들다basename.

확장자가 없는 salt 파일 이름입니다.

echo "$FILE_PATH" | sed -r "s/.+\/(.+)\..+/\1/"

돌아옵니다test.old.

그리고 다음 진술은 다음과 같은 완전한 경로를 제공합니다.dirname지휘권

echo "$FILE_PATH" | sed -r "s/(.+)\/.+/\1/"

돌아옵니다/opt/datastores/sda2

경로에서 파일 이름을 가져오는 쉬운 방법은 다음과 같습니다.

echo "$PATH" | rev | cut -d"/" -f1 | rev

파일 이름에 점이 하나(확장자 점)만 있다고 가정하여 사용할 수 있는 확장자를 제거하려면:

cut -d"." -f1
$ file=${$(basename $file_path)%.*}

정규식(regi?)이 멋지기 때문에 몇 가지 더 다른 대안이 있습니다!

다음은 작업을 수행하는 단순 정규식입니다.

 regex="[^/]*$"

예(grep):

 FP="/hello/world/my/file/path/hello_my_filename.log"
 echo $FP | grep -oP "$regex"
 #Or using standard input
 grep -oP "$regex" <<< $FP

예(awk):

 echo $FP | awk '{match($1, "$regex",a)}END{print a[0]}
 #Or using stardard input
 awk '{match($1, "$regex",a)}END{print a[0]} <<< $FP

더 복잡한 정규식이 필요한 경우: 예를 들어 경로가 문자열로 감싸여 있습니다.

 StrFP="my string is awesome file: /hello/world/my/file/path/hello_my_filename.log sweet path bro."

 #this regex matches a string not containing / and ends with a period 
 #then at least one word character 
 #so its useful if you have an extension

 regex="[^/]*\.\w{1,}"

 #usage
 grep -oP "$regex" <<< $StrFP

 #alternatively you can get a little more complicated and use lookarounds
 #this regex matches a part of a string that starts with /  that does not contain a / 
 ##then uses the lazy operator ? to match any character at any amount (as little as possible hence the lazy)
 ##that is followed by a space
 ##this allows use to match just a file name in a string with a file path if it has an exntension or not
 ##also if the path doesnt have file it will match the last directory in the file path 
 ##however this will break if the file path has a space in it.

 regex="(?<=/)[^/]*?(?=\s)"

 #to fix the above problem you can use sed to remove spaces from the file path only
 ## as a side note unfortunately sed has limited regex capibility and it must be written out in long hand.
 NewStrFP=$(echo $StrFP | sed 's:\(/[a-z]*\)\( \)\([a-z]*/\):\1\3:g')
 grep -oP "$regex" <<< $NewStrFP

정규식을 사용한 토탈 솔루션:

이 함수는 파일 이름에 여러 개의 ".s"가 있더라도 Linux 파일 경로의 확장자가 있거나 없는 파일 이름을 제공할 수 있습니다.또한 파일 경로의 공백과 파일 경로가 포함되어 있거나 문자열로 묶인 경우에도 처리할 수 있습니다.

#you may notice that the sed replace has gotten really crazy looking
#I just added all of the allowed characters in a linux file path
function Get-FileName(){
    local FileString="$1"
    local NoExtension="$2"
    local FileString=$(echo $FileString | sed 's:\(/[a-zA-Z0-9\<\>\|\\\:\)\(\&\;\,\?\*]*\)\( \)\([a-zA-Z0-9\<\>\|\\\:\)\(\&\;\,\?\*]*/\):\1\3:g')

    local regex="(?<=/)[^/]*?(?=\s)"

    local FileName=$(echo $FileString | grep -oP "$regex")

    if [[ "$NoExtension" != "" ]]; then
        sed 's:\.[^\.]*$::g' <<< $FileName
    else
        echo "$FileName"
    fi
}

## call the function with extension
Get-FileName "my string is awesome file: /hel lo/world/my/file test/path/hello_my_filename.log sweet path bro."

##call function without extension
Get-FileName "my string is awesome file: /hel lo/world/my/file test/path/hello_my_filename.log sweet path bro." "1"

창 경로를 잘못 사용해야 하는 경우 다음 경로로 시작할 수 있습니다.

 [^\\]*$       
$ source_file_filename_no_ext=${source_file%.*}
$ echo ${source_file_filename_no_ext##*/}

언급URL : https://stackoverflow.com/questions/3362920/get-just-the-filename-from-a-path-in-a-bash-script

반응형