파일이나 폴더를 압축할 때 일반적으로 수행하는 모든 단계를 수행하는 zip 기능을 만들려고 합니다. 내 현재 디렉터리가 ~
이고 이름이 지정된 폴더를 압축 Folder1
하고 해당 파일 경로는 ~/Folder2/Folder1
.
발행 된
cd ~/Folder2 && zip -r Folder1 Folder1 && cd -
정확히 내가 원했던 것입니다. 즉, 출력에 Folder1.zip
압축 중인 폴더(예: )로 연결되는 폴더가 포함되지 않도록 압축하고 /home/user/Folder2
, 재귀적으로 압축하며, 압축하려는 파일과 동일한 이름으로 압축하는 첫 번째 인수를 허용합니다. 또는 폴더의 이름이 정확히 같습니다. 지퍼( Folder1.zip
).
.zshrc
그래서 나는 내 물건 에 다음과 같은 것을 만들고 싶습니다 .
coolerzip() { cd /path/to/file && zip -r file file && cd - }
하나의 매개변수만 허용하면 되며, 이 경우에는 ~/Folder2/Folder1
. 그런 다음 Folder1
두 s의 이름이 되며 압축하기 전에 현재 디렉터리의 so로 직접 이동합니다. 세 개가 아닌 하나의 매개변수만 필요하도록 이를 달성할 수 있는 방법이 있습니까?file
coolerzip
cd
~/Folder2
Folder1
coolerzip
답변1
이 함수의 매개변수는 입니다 $1
.
당신은 그것을 사용할 수 있습니다역사 확장 수정자디렉터리 부분과 경로의 마지막 구성 요소를 추출합니다. 인수가 이면 is 및 is ~/directory2/directory1
입니다 . (기억법: ead and ail.)$1:h
~/directory2
$1:t
directory1
h
t
함수 본문 주위에 중괄호 대신 괄호를 사용하십시오. 이런 방식으로 함수 본문은 서브쉘(별도의 쉘 프로세스)에서 실행되며 변수 할당, 디렉토리 변경 등은 서브쉘에만 영향을 미칩니다.
coolerzip () (
cd $1:h &&
zip -r $2:h.zip $2:h
)
다른 쉘에는 기록 확장 수정자가 없으므로 인수를 구문 분석하려면 다른 것이 필요합니다. 파일 이름의 경우 ${1##*/}
모든 선행 디렉터리 구성 요소를 제거합니다. 그러나 이 방법은 인수에 후행 슬래시가 있으면 작동하지 않지만 "$(basename -- "$1")"
이 경우에는 작동합니다. 기본 디렉토리의 경우 를 사용하십시오 $(dirname -- "$1")
. zsh 이외의 쉘에서는 다음이 필요합니다.변수 대체 주위에 큰따옴표 추가.
coolerzip () (
name="$(basename -- "$1")"
cd "$(dirname -- "$1")" &&
zip -r "$name.zip" "$name"
)
답변2
저는 zsh 사용자는 아니지만 다음은 bash에서 작동하지만 그렇지 않습니다.생각하다특정 bashism과 함께 작동하므로 다음과 같이 작업을 수행해야 합니다.
coolerzip() { cd "${1%/*}" && zip -r "${1##*/}" "${1##*/}" && cd -; }
$1
참조할 스크립트나 함수의 위치 매개변수입니다.첫 번째명령줄에서 스크립트나 함수에 제공되는 인수입니다. 스크립트 또는 함수 이름(0번째 인수)을 제공하고, $2
0 번째 인수를 제외한 각 인수를 제공하고, 인수 수(역시 0번째 인수 매개변수 제외)를 제공합니다 . 명령줄(또는 모든 셸)에서 호출하면 상황이 다르게 작동 하지만 여기서는 이에 대해 논의하지 않겠습니다.$9
$0
$@
$#
sh -c
${1%/*}
$1
제거된 glob 패턴 중 가장 짧은 일치 값을 반환합니다 */
(원하는 경우).가장 긴마지막에 일치하면 %%
)를 사용합니다. 그러면 함수에 제공한 경로의 마지막 부분이 제거됩니다. 패턴 시작 부분에서 가장 긴 일치 항목을 ${1##*/}
제거합니다 (시작 부분에서 가장 짧은 일치 항목의 경우 단일 사용 ).*/
$1
#
위의 함수는 약간 취약합니다. ~/folder1/folder2/
인수에 후행 슬래시(예를 들어)가 있으면 중단됩니다. 인수가 슬래시가 없는 단일 디렉터리 이름인 경우 다르게 구분됩니다. 이 문제를 해결하는 간단한 방법은 readlink
명령을 사용하여 입력 인수의 전체 경로를 반환하는 것입니다(적어도 내 Ubuntu 시스템에서는 후행 슬래시도 제거합니다).
coolerzip() { a="$(readlink -f "$1")"; cd "${a%/*}" && zip -r "${a##*/}" "${a##*/}" && cd -; }