답변:
basename
GNU coreutils 에서이 작업을 수행하는 데 도움이 될 수 있습니다.
$ basename /root/video.mp4
video.mp4
파일의 확장자를 이미 알고 있다면, 파일 을 제거하기 위해 basename
구문 basename NAME [SUFFIX]
을 사용하여 호출 할 수 있습니다 .
$ basename /root/video.mp4 .mp4
video
또는 다른 옵션은 다음을 사용하여 마지막 점 이후의 모든 것을 자르는 것입니다 sed
.
$ basename /root/video.old.mp4 | sed 's/\.[^.]*$//'
video.old
다음 방법 중 하나를 사용하십시오.
out_file="${in_file##*/}"
out_file="$(basename $in_file)"
out_file="$(echo $in_file | sed 's=.*/==')"
out_file="$(echo $in_file | awk -F"/" '{ print $NF }')"
추신. 명령문 \(.*\.\)
에서 처음부터 점 ( /root/video.
) 까지 문자열과 일치 하므로 동일한 문자열 을 얻은 다음 .mp4
원래 문자열과 동일한 문자열 을 수동으로 추가 합니다. s=.*\([^/]*\)=\1=
대신 사용해야 합니다.
업데이트 : (첫 번째는 지금 수정되었습니다)
확장자가없는 유일한 파일 이름을 얻으려면 다음을 수행하십시오.
out_file="$(echo $in_file | sed 's=.*/==;s/\.[^.]*$/.new_ext/')"
out_file="$(echo $in_file | sed 's=\([^/]*\)\.[^./]*$=\1.new_ext=')"
out_file="$(echo $in_file | awk -F"/" '{ gsub (/\.[^/.]*$/,".new_ext",$NF);print $NF }'
my.file.tar.gz
.
sed
및 누락 된 점 기호가있었습니다 awk
. 결정된. 감사합니다.
정규식을 사용하는 기본 요소 중 하나는 와일드 카드를 지정할 때 패턴이 본질적으로 욕심이다는 것입니다. @uloBasEI가 제안한 답변은 확실한 답변이지만 basename 명령을 사용해야합니다. @Shixons의 원래 질문은 sed 만 사용하여 솔루션을 요청합니다.
계속하기 전에, 어느 버전의 sed가 대상인지 아는 것이 항상 도움이됩니다. BSD를 가정하고 있습니다 (OSX와 함께 제공됨).
우선, 원래 질문에서 제안 된 패턴은 입력 문자열의 시작부터 마지막 점까지의 모든 것을 캡처하기 때문에 작동하지 않습니다. 앵커가 없으면이 검색은 모든 것을 왼쪽에서 오른쪽으로 삼 킵니다. 따라서 "/ 1"일치 패턴은 마지막 점까지 모든 것을 포함합니다. 여러 개의 점이있는 파일 이름도 전체적으로 삼켜집니다. 원하는 결과가 아닙니다.
첫 번째 단계는 패턴을 식별하기위한 전략을 수립하는 것입니다. 여기에서 파일 이름 왼쪽에있는 모든 것을 제거하고 싶습니다 (나중에 확장명을 다룰 것입니다).
out_file="$(echo $in_file | sed 's/^\(\/.*\/\)*.*/\1/')"
문자열의 처음부터 검색이 일치합니다. "/.*"패턴을 0 번 이상 일치시키고 나중에 모든 것을 삭제합니다. 일치하는 패턴을 "\ 1"로 인쇄합니다. 우리는 전 세계적으로 검색하지 않습니다. ^ 앵커를 지정하여 문자열의 처음부터 검색합니다.
"-E"옵션을 활성화하여 명확성을 높이면 괄호를 피할 필요가 없습니다.
out_file="$(echo $in_file | sed -E 's/^(\/.*\/)*.*/\1/')"
이제 왼쪽에 부분이 있습니다. 오른쪽 부분을 추가합시다. 왼쪽 부분을 패턴으로 유지해야하므로 0 번 이상 나타나도록 지정할 수 있습니다. 우리가 지금하는 일은 오른쪽 부분에 패턴을 추가하는 것입니다.
out_file="$(echo $in_file | sed -E 's/^(\/.*\/)*(.*)/\2/')"
두 번째 일치 항목 만 인쇄하여 파일 이름 이외의 모든 것을 버립니다. 그러나 여전히 파일 이름 확장자를 제거해야합니다.
out_file="$(echo $in_file | sed -E 's/^(\/.*\/)*(.*)\..*$/\2/')"
끝에있는 "$"는 선택 사항입니다.
마지막으로 새 확장을 추가하려면 다음과 같이 수정하십시오.
out_file="$(echo $in_file | sed -E 's/^(\/.*\/)*(.*)\..*$/\2.mp4/')"
추가 최적화는 상대 경로를 처리하기 위해 첫 번째 슬래시를 선택적으로 만드는 것입니다.
out_file="$(echo $in_file | sed -E 's/^([\/]?.*\/)*(.*)\..*$/\2.mp4/')"
나는 basename 을 대체 할 sed 패턴을 찾는 동안 게 으르 면서이 질문을 보았습니다 . 해당 명령이 설치되지 않은 벗겨진 시스템에서 작업하고 있습니다.
sed 's/\.[^.]*$//'
당신이 가지고, (숨겨진)에 대한 실패.filename
와.
및..
디렉토리