Zsh 개발 안내서 (제1 9 편 스 크 립 트 실례 설명)
본 고 는 비교적 간단 한 zsh 스 크 립 트 인 스 턴 스 를 설명 할 것 이다.
인 스 턴 스 1: 디 렉 터 리 의 디 렉 터 리 구 조 를 복사 합 니 다.
기능:
디 렉 터 리 와 그 아래 에 있 는 모든 디 렉 터 리 를 다른 디 렉 터 리 로 복사 하지만 디 렉 터 리 에 있 는 다른 종류의 파일 은 복사 하지 않 습 니 다.
예:
src 的目录结构:
src
├── a
├── b
│   ├── 1.txt
│   └── 2
│       └── 3.txt
├── c.txt
├── d
├── e f
│   └── g
│       └── 4.txt
└── g h -> e f
要构造一个 dst 目录,只包含 src 下的目录,内容如下:
dst
└── src
    ├── a
    ├── b
    │   └── 2
    ├── d
    └── e f
        └── g생각:
**/*(/) 로 일치 할 수 있 습 니 다.# 参数 1:src 目录
# 参数 2:待创建的 dst 目录
#!/bin/zsh
for i ($1/**/*(/)) {
    # -p 参数是递归创建目录,这样不用考虑目录的创建顺序
    mkdir -p $2/$i
}실례 2: 짝 이 맞지 않 는 파일 찾기
기능:
현재 디 렉 터 리 에. txt 와. txt. md5sum 파일 이 있어 야 합 니 다. 대응 하 는. md5sum 파일 이 없 는. txt 파일 을 찾 아야 합 니 다.(실제 장면 은 다운로드 가 완 료 된 파일 을 찾 는 것 입 니 다. 다운로드 가 완료 되 지 않 은 파일 은 모두 접미사 가 있 는 파일 에 대응 합 니 다.)
예:
当前目录的所有文件:
aa.txt
bb.txt
bb.txt.md5sum
cc dd.txt
cc dd.txt.md5sum
ee ff.txt.md5sum
gg.txt
hh ii.txt
需要找出没有对应 .md5sum 的 .txt 文件:
aa.txt
gg.txt
hh ii.txt생각:
실현:
#!/bin/zsh
all_files=(*)
bad_files=(*.md5sum)
bad_files+=(${bad_files/.md5sum})
# 数组差集操作
echo ${all_files:|bad_files}인 스 턴 스 3: sed 대량 으로 파일 이름 바 꾸 기
기능:
sed 명령 과 같은 형식 으로 파일 이름 을 대량으로 바 꿉 니 다.
예:
# 实现 renamex 命令,接受的第一个参数为 sed 的主体参数,其余参数是文件列表
# 效果是根据 sed 对文件名的修改重命名这些文件
% tree
.
├── aaa_aaa.txt
├── aaa.txt
├── ccc.txt
└── xxx
    ├── aaa bbb.txt
    └── bbb ccc.txt
% renamex s/aaa/bbb/g **/*
'aaa_aaa.txt' -> 'bbb_bbb.txt'
'aaa.txt' -> 'bbb.txt'
'xxx/aaa bbb.txt' -> 'xxx/bbb bbb.txt'
% tree
.
├── bbb_bbb.txt
├── bbb.txt
├── ccc.txt
└── xxx
    ├── bbb bbb.txt
    └── bbb ccc.txt생각:
#!/bin/zsh
(($+2)) || {
    echo 'Usage: renamex s/aaa/bbb/g *.txt'
    return
}
for name ($*[2,-1]) {
    local new_name="$(echo $name | sed $1)"
    [[ $name == $new_name ]] && continue
    mv -v $name $new_name
}인 스 턴 스 4: 파일 의 md5 에 따라 중복 파일 삭제
기능:
현재 디 렉 터 리 와 하위 디 렉 터 리 에 있 는 모든 중복 파일 을 삭제 합 니 다 (md5 에 따라 엄밀 하지 않 습 니 다).
생각:
실현:
#!/bin/zsh
# D 是包含以 . 开头的隐藏文件
local files=("${(f)$(md5sum **/*(.D))}")
local files_to_delete=()
local -A md5s
for i ($files) {
    # 取前 32 位,即 md5 的长度
    local md5=$i[1,32]
    if (($+md5s[$md5])) {
        # 取 35 位之后的内容,即文件路径,md5 后边有两个空格
        files_to_delete+=($i[35,-1])
    } else {
        md5s[$md5]=1
    }
}
(($#files_to_delete)) && rm -v $files_to_delete인 스 턴 스 5: 100 이내 의 한자 숫자 를 아라비아 숫자 로 변환 합 니 다.
기능:
100 이내 의 한자 숫자 를 아라비아 숫자 로 바 꾸 는데, 예 를 들 어 68 에서 68 로 전환한다.
생각:
실현:
#!/bin/zsh
local -A table=(
零 0
一 1
二 2
三 3
四 4
五 5
六 6
七 7
八 8
九 9
)
local result
if [[ $1 == 十 ]] {
    result=一零
} elif [[ $1 == 十* ]] {
    result=${1/十/一}
} elif [[ $1 == *十 ]] {
    result=${1/十/零}
} elif [[ $1 == *十* ]] {
    result=${1/十}
} else {
    result=$1
}
for i ({1..$#result}) {
    result[i]=$table[$result[i]]
    if [[ -z $result[i] ]] {
        echo error
        return 1
    }
}
echo $result
运行结果:
% ./convert 一
1
% ./convert 十
10
% ./convert 十五
15
% ./convert 二十
20
% ./convert 五十六
56
% ./convert 一百
error인 스 턴 스 6: 중국어 한자 숫자 가 있 는 파일 이름 을 숫자 로 시작 합 니 다.
기능:
다음 예 를 보시오.
예:
当前目录有如下文件:
Zsh-开发指南(第一篇-变量和语句).md
Zsh-开发指南(第七篇-数值计算).md
Zsh-开发指南(第三篇-字符串处理之转义字符和格式化输出).md
Zsh-开发指南(第九篇-函数和脚本).md
Zsh-开发指南(第二篇-字符串处理之常用操作).md
Zsh-开发指南(第五篇-数组).md
Zsh-开发指南(第八篇-变量修饰语).md
Zsh-开发指南(第六篇-哈希表).md
Zsh-开发指南(第十一篇-变量的进阶内容).md
Zsh-开发指南(第十七篇-使用-socket-文件和-TCP-实现进程间通信).md
Zsh-开发指南(第十三篇-管道和重定向).md
Zsh-开发指南(第十九篇-脚本实例讲解).md
Zsh-开发指南(第十二篇-[[-]]-的用法).md
Zsh-开发指南(第十五篇-进程与作业控制).md
Zsh-开发指南(第十八篇-更多内置模块的用法).md
Zsh-开发指南(第十六篇-alias-和-eval-的用法).md
Zsh-开发指南(第十四篇-文件读写).md
Zsh-开发指南(第十篇-文件查找和批量处理).md
Zsh-开发指南(第四篇-字符串处理之通配符).md
需要重命名成这样:
01_Zsh-开发指南(第一篇-变量和语句).md
02_Zsh-开发指南(第二篇-字符串处理之常用操作).md
03_Zsh-开发指南(第三篇-字符串处理之转义字符和格式化输出).md
04_Zsh-开发指南(第四篇-字符串处理之通配符).md
05_Zsh-开发指南(第五篇-数组).md
06_Zsh-开发指南(第六篇-哈希表).md
07_Zsh-开发指南(第七篇-数值计算).md
08_Zsh-开发指南(第八篇-变量修饰语).md
09_Zsh-开发指南(第九篇-函数和脚本).md
10_Zsh-开发指南(第十篇-文件查找和批量处理).md
11_Zsh-开发指南(第十一篇-变量的进阶内容).md
12_Zsh-开发指南(第十二篇-[[-]]-的用法).md
13_Zsh-开发指南(第十三篇-管道和重定向).md
14_Zsh-开发指南(第十四篇-文件读写).md
15_Zsh-开发指南(第十五篇-进程与作业控制).md
16_Zsh-开发指南(第十六篇-alias-和-eval-的用法).md
17_Zsh-开发指南(第十七篇-使用-socket-文件和-TCP-实现进程间通信).md
18_Zsh-开发指南(第十八篇-更多内置模块的用法).md
19_Zsh-开发指南(第十九篇-脚本实例讲解).md생각:
실현:
#!/bin/zsh
# 转换数字的逻辑和上一个实例一样
local -A table=(
零 0
一 1
二 2
三 3
四 4
五 5
六 6
七 7
八 8
九 9
)
convert() {
    local result
    if [[ $1 == 十 ]] {
        result=一零
    } elif [[ $1 == 十* ]] {
        result=${1/十/一}
    } elif [[ $1 == *十 ]] {
        result=${1/十/零}
    } elif [[ $1 == *十* ]] {
        result=${1/十}
    } else {
        result=$1
    }
    for i ({1..$#result}) {
        result[i]=$table[$result[i]]
        if [[ -z $result[i] ]] {
            echo error
            return 1
        }
    }
    echo $result
}
for i (Zsh*.md) {
    # -Z 2 是为了在前边补全一个 0
    # 把文件名“第”之前和“篇”之后的全部去除
    local -Z 2 num=$(convert ${${i#*第}%篇*})
    mv -v $i ${num}_$i
}인 스 턴 스 7: 압축 해제 도구 통일
기능:
Linux 에서 자주 사용 하 는 압축, 압축 파일 형식 이 많 고 매개 변수 가 각각 다 릅 니 다. 용법 이 통 일 된 압축 해제 도 구 를 작성 하여 압력
mkdir -p .zip .7z .tar .tgz .tbz2 .txz .tar.gz .tar.bz2 .tar.xz .cpio .ar .gz .bz2 .xz 등 파일 을 만 드 는 데 사 용 됩 니 다.(유사 atool 하지만 atool 오 랜 만 에 업데이트 되 었 습 니 다. 일부 새로운 형식 은 지원 되 지 않 아 맞 춤 형 제작 이 불가능 합 니 다. 그것 도 perl 으로 써 서 알 아 보기 어렵 습 니 다. 그래서 스스로 쓰기 로 결 정 했 습 니 다. atool 의 일부 상용 기능 만 덮어 쓰기 로 결 정 했 습 니 다.)예:
# a 用于创建压缩文件
% a a.tgz dir1 file1 file2
dir1/
file1
file2
# al 用于列出压缩文件中的文件列表
% al a.tgz
drwxr-xr-x goreliu/goreliu   0 2017-09-13 11:23 dir1/
-rw-r--r-- goreliu/goreliu   3 2017-09-13 11:23 file1
-rw-r--r-- goreliu/goreliu   3 2017-09-13 11:23 file2
# x 用于解压文件
% x a.tgz
dir1/
file1
file2
a.tgz  ->  a
# 如果解压后的文件名或目录名中当前目录下已经存在,则解压到随机目录
% x a.tgz
dir1/
file1
file2
a.tgz  ->  /tmp/test/x-c4I생각:
file 명령 결과 에 따라 압축 파일 의 형식 을 판단 합 니 다.ln -s 여러 명령 이 된다.실현:
#!/bin/zsh
get_type_by_name() {
    case $1 {
        (*.zip|*.7z|*.jar)
        echo 7z
        ;;
        (*.rar|*.iso)
        echo 7z_r
        ;;
        (*.tar|*.tgz|*.txz|*.tbz2|*.tar.*)
        echo tar
        ;;
        (*.cpio)
        echo cpio
        ;;
        (*.cpio.*)
        echo cpio_r
        ;;
        (*.gz)
        echo gz
        ;;
        (*.xz)
        echo xz
        ;;
        (*.bz2)
        echo bz2
        ;;
        (*.lzma)
        echo lzma
        ;;
        (*.lz4)
        echo lz4
        ;;
        (*.ar)
        echo ar
        ;;
        (*)
        return 1
        ;;
    }
}
get_type_by_file() {
    case $(file -bz $1) {
        (Zip *|7-zip *)
        echo 7z
        ;;
        (RAR *)
        echo 7z_r
        ;;
        (POSIX tar *|tar archive)
        echo tar
        ;;
        (*cpio archive*)
        echo cpio
        ;;
        (*gzip *)
        echo gz
        ;;
        (*XZ *)
        echo xz
        ;;
        (*bzip2 *)
        echo bz2
        ;;
        (*LZMA *)
        echo lzma
        ;;
        (*LZ4 *)
        echo lz4
        ;;
        (current ar archive)
        echo ar
        ;;
        (*)
        return 1
        ;;
    }
}
(($+commands[tar])) || alias tar=bsdtar
(($+commands[cpio])) || alias cpio=bsdcpio
case ${0:t} {
    (a)
    (($#* >= 2)) || {
        echo Usage: $0 target files/dirs
        return 1
    }
    case $(get_type_by_name $1) {
        (7z)
        7z a $1 $*[2,-1]
        ;;
        (tar)
        tar -cavf $1 $*[2,-1]
        ;;
        (cpio)
        find $*[2,-1] -print0 | cpio -H newc -0ov > $1
        ;;
        (gz)
        gzip -cv $*[2,-1] > $1
        ;;
        (xz)
        xz -cv $*[2,-1] > $1
        ;;
        (bz2)
        bzip2 -cv $*[2,-1] > $1
        ;;
        (lzma)
        lzma -cv $*[2,-1] > $1
        ;;
        (lz4)
        lz4 -cv $2 > $1
        ;;
        (ar)
        ar rv $1 $*[2,-1]
        ;;
        (*)
        echo $1: error
        return 1
        ;;
    }
    ;;
    (al)
    (($#* >= 1)) || {
        echo Usage: $0 files
        return 1
    }
    for i ($*) {
        case $(get_type_by_name $i || get_type_by_file $i) {
            (7z|7z_r)
            7z l $i
            ;;
            (tar)
            tar -tavf $i
            ;;
            (cpio|cpio_r)
            cpio -itv < $i
            ;;
            (gz)
            zcat $i
            ;;
            (xz)
            xzcat $i
            ;;
            (bz2)
            bzcat $i
            ;;
            (lzma)
            lzcat $i
            ;;
            (lz4)
            lz4cat $i
            ;;
            (ar)
            ar tv $i
            ;;
            (*)
            echo $i: error
            ;;
        }
    }
    ;;
    (x)
    (($#* >= 1)) || {
        echo Usage: $0 files
        return 1
    }
    for i ($*) {
        local outdir=${i%.*}
        [[ $outdir == *.tar ]] && {
            outdir=$outdir[1, -5]
        }
        if [[ -e $outdir ]] {
            outdir="$(mktemp -d -p $PWD x-XXX)"
        } else {
            mkdir $outdir
        }
        case $(get_type_by_name $i || get_type_by_file $i) {
            (7z|7z_r)
            7z x $i -o$outdir
            ;;
            (tar)
            tar -xavf $i -C $outdir
            ;;
            (cpio|cpio_r)
            local file_path=$i
            [[ $i != /* ]] && file_path=$PWD/$i
            cd $outdir && cpio -iv < $file_path && cd ..
            ;;
            (gz)
            zcat $i > $outdir/$i[1,-4]
            ;;
            (xz)
            xzcat $i > $outdir/$i[1,-4]
            ;;
            (bz2)
            bzcat $i > $outdir/$i[1,-5]
            ;;
            (lzma)
            lzcat $i > $outdir/$i[1,-6]
            ;;
            (lz4)
            lz4cat $i > $outdir/$i[1,-5]
            ;;
            (ar)
            local file_path=$i
            [[ $i != /* ]] && file_path=$PWD/$i
            cd $outdir && ar x $file_path && cd ..
            ;;
            (*)
            echo $i: error
            ;;
        }
        local files=$(ls -A $outdir)
        if [[ -z $files ]] {
            rmdir $outdir
        } elif [[ -e $outdir/$files && ! -e $files ]] {
            mv -v $outdir/$files . && rmdir $outdir
            echo $i " -> " $files
        } else {
            echo $i " -> " $outdir
        }
    }
    ;;
    (*)
    echo error
    return 1
    ;;
}인 스 턴 스 8: 명령 을 동시에 실행 할 수 있 는 도구
기능:
우 리 는 반복 적 으로 파일 을 대량으로 처리 하 는 장면 (예 를 들 어 모든 jpg 그림 을 png 그림 으로 변환 하 는 것) 을 자주 볼 수 있 습 니 다. 그러면 번 거 로 움 을 만 날 수 있 습 니 다. 만약 에 프런트 에서 파일 을 처리 하면 같은 시간 에 하나만 처리 할 수 있 고 효율 이 너무 낮 습 니 다.배경 에서 파일 을 처리 하면 순식간에 여러 프로 세 스 가 시작 되 고 많은 자원 을 차지 하 며 시스템 이 감당 하기 어렵다.우리 가 원 하 는 것 은 같은 시간 에 최대 10 개의 고정 수량 (예 를 들 어 10 개) 의 파일 을 동시에 처리 하 는 것 입 니 다. 만약 에 이 수량 에 이 르 렀 다 면 잠시 기 다 렸 다가 종료 하 는 프로 세 스 가 있 을 때 까지 기 다 렸 다가 계속 하 는 것 입 니 다.
parallel 명령 에서 어느 정도 이 수 요 를 만족 시 킬 수 있 지만 사용 하기 가 너무 번거롭다.예:
# rr 是一个函数(可放在 .zshrc 中),直接 rr 加命令即可使用
# 命令中支持变量、重定向等等,格式上和直接输入命令没有区别(不支持 alias)
% rr sleep 5
[4] 5031
% rr sleep 5
[5] 5032
# 如果不加参数,则显示当前运行的进程数、最大进程并发数和运行中进程的进程号
# 默认最大进程并发数是 10
% rr
running/max: 2/10
pid: 5031 5032
# 5 秒之后,运行结束
% rr
running/max: 0/10
# 用 -j 来指定最大进程并发数,指定一次即可,如需修改可再次指定
# 可以只调整最大进程并发数而不运行命令
% rr -j2 sleep 10
[4] 5035
% rr sleep 10
[5] 5036
# 超过了最大进程并发数,等待,并且每一秒检查一次是否有进程退出
# 如果有进程退出,则继续在后台运行当前命令
% rr sleep 10
running/max: 2/2, wait 1s ...
pid: 5035 5036
running/max: 2/2, wait 1s ...
pid: 5035 5036
[4]  - done       $*
[4] 5039
# 实际使用场景,批量将 jpg 图片转换成 png 图片,gm 是 graphicsmagick 中的命令
# 转换图片格式比较耗时,顺序执行的话需要很久
% for i (*.jpg) { rr gm convert $i ${i/jpg/png} }
[4] 5055
[5] 5056
[6] 5057
[7] 5058
[8] 5059
[9] 5060
[10] 5061
[11] 5062
[12] 5063
[13] 5064
running/max: 10/10, wait 1s ...
pid: 5060 5061 5062 5063 5064 5055 5056 5057 5058 5059
running/max: 10/10, wait 1s ...
pid: 5060 5061 5062 5063 5064 5055 5056 5057 5058 5059
[11]    done       $*
[5]    done       $*
[5] 5067
[12]    done       $*
[11] 5068
[6]    done       $*
[6] 5069
[12] 5070
running/max: 10/10, wait 1s ...
pid: 5070 5060 5061 5064 5055 5067 5068 5069 5058 5059
[13]  - done       $*
[4]    done       $*
[4] 5072
[13] 5073
running/max: 10/10, wait 1s ...
pid: 5070 5060 5072 5061 5073 5067 5068 5069 5058 5059
[5]    done       $*
[6]    done       $*
[5] 5075
[6] 5076
running/max: 10/10, wait 1s ...
pid: 5070 5060 5072 5061 5073 5075 5076 5068 5058 5059
...생각:
실현:
rr() {
    (($+max_process)) || typeset -g max_process=10
    (($+running_process)) || typeset -gA running_process=()
    [[ $1 == -j<1-> ]] && {
        max_process=${1[3,-1]}
        shift
    }
    (($# == 0)) && {
        for i (${(k)running_process}) {
            [[ -e /proc/$i ]] || unset "running_process[$i]"
        }
        echo "running/max: $#running_process/$max_process"
        (($#running_process > 0)) && echo "pid: ${(k)running_process}"
        return
    }
    while ((1)) {
        local running_process_num=$#running_process
        if (($running_process_num < max_process)) {
            $* &
            running_process[$!]=1
            return
        }
        for i (${(k)running_process}) {
            [[ -e /proc/$i ]] || unset "running_process[$i]"
        }
        (($#running_process == $running_process_num)) && {
            echo "running/max: $running_process_num/$max_process, wait 1s ..."
            echo "pid: ${(k)running_process}"
            sleep 1
        }
    }
}인 스 턴 스 9: 그림 형식 일괄 변환
기능:
현재 디 렉 터 리 와 하위 디 렉 터 리 의 모든 일반적인 그림 형식 을 jpg 형식 으로 바 꾸 고 (jpg 형식 도 한 번 바 꾸 면 파일 의 부 피 를 줄 일 수 있 습 니 다) 원본 그림 을 삭제 합 니 다.다섯 개의 병행 프로 세 스 로 처리 해 야 합 니 다.확장자 가 다른 파일 만 서로 덮어 쓰 는 경 우 를 피하 십시오.
예:
% tree
.
├── mine
│   ├── 信.txt
│   ├── 第一封信.jpg
│   └── 第二封信.JPG
├── 搞笑
│   ├── 卖萌.GIF
│   ├── 猫吃鱼.gif
│   └── 猫抢东西吃.gif
└── 素材
    ├── 104 按键模板.jpg
    ├── 104 按键模板.psd
    ├── ahk
    │   ├── ahk_bg.jpg
    │   ├── ahk_home_logo.jpg
    │   ├── ahk_home_logo.txt
    │   ├── ahk_home_qr.jpg
    │   ├── ahk_home_qr_small.jpg
    │   └── ahk_logo.png
    ├── stp_fc_cw_png_pk
    │   ├── HD.PNG
    │   ├── newimage.png
    │   ├── nshd.PNG
    │   └── std.png
    ├── 地球.jpg
    ├── 星系.JPEG
    ├── 木纹 背景.GIF
    ├── 木纹 背景.jpeg
    └── 木纹 背景.jpg
5 directories, 23 files
% alltojpg
running/max: 0/5
running: 5, wait 1.0000000000s ...
pid: 5953 5954 5955 5956 5957
running: 5, wait 1.0000000000s ...
pid: 5965 5966 5967 5968 5959
% tree
.
├── mine
│   ├── 信.txt
│   ├── 第一封信.jpg
│   └── 第二封信.jpg
├── 搞笑
│   ├── 卖萌_g.jpg
│   ├── 猫吃鱼_g.jpg
│   └── 猫抢东西吃_g.jpg
└── 素材
    ├── 104 按键模板.jpg
    ├── 104 按键模板.psd
    ├── ahk
    │   ├── ahk_bg.jpg
    │   ├── ahk_home_logo.jpg
    │   ├── ahk_home_logo.txt
    │   ├── ahk_home_qr.jpg
    │   ├── ahk_home_qr_small.jpg
    │   └── ahk_logo_p.jpg
    ├── stp_fc_cw_png_pk
    │   ├── HD_p.jpg
    │   ├── newimage_p.jpg
    │   ├── nshd_p.jpg
    │   └── std_p.jpg
    ├── 地球.jpg
    ├── 星系_e.jpg
    ├── 木纹 背景_e.jpg
    ├── 木纹 背景_g.jpg
    └── 木纹 背景.jpg
5 directories, 23 files생각:
gm convert 명령 (graphicsmagick 중) 또는 convert 명령 (imagemagick 중).jpg jpeg png gif 이 고 대문자 확장자 일 수 있 습 니 다.a.gif 덮어 쓰기 a.jpg 를 피하 기 위해 서로 다른 파일 형식 에 서로 다른 접 두 사 를 추가 하면 같은 이름 의 파일 이 있 는 지 확인 하지 않 고 속 도 를 낼 수 있다.실현:
#!/bin/zsh
# rr 是上一个实例中代码的改进版本
rr() {
    (($+max_process)) || typeset -gi max_process=10
    (($+check_interval)) || typeset -gF check_interval=1
    (($+running_process)) || typeset -gA running_process=()
    while {getopts i:j:h arg} {
        case $arg {
            (i)
            ((OPTARG > 0)) && check_interval=$OPTARG
            ;;
            (j)
            ((OPTARG > 0)) && max_process=$OPTARG
            ;;
            (h)
            echo "Usage: $0 [-i check_interval] [-j max_process] [cmd] [args]"
            return
            ;;
        }
    }
    shift $((OPTIND - 1))
    (($# == 0)) && {
        for i (${(k)running_process}) {
            [[ -e /proc/$i ]] || unset "running_process[$i]"
        }
        echo "running/max: $#running_process/$max_process"
        (($#running_process > 0)) && echo "pid: ${(k)running_process}"
        return 0
    }
    while ((1)) {
        local running_process_num=$#running_process
        if (($running_process_num < max_process)) {
            $* &
            running_process[$!]=1
            return
        }
        for i (${(k)running_process}) {
            [[ -e /proc/$i ]] || unset "running_process[$i]"
        }
        (($#running_process == $running_process_num)) && {
            echo "running: $running_process_num, wait ${check_interval}s ..."
            echo "pid: ${(k)running_process}"
            sleep $check_interval
        }
    }
}
# JPG 作为中间扩展名
rename .JPG .jpg **/*.JPG
# 设置进程并发数为 5
rr -j5
for i (**/*.(jpg|png|PNG|jpeg|JPEG|gif|GIF)) {
    rr gm convert $i $i.JPG
}
# 等所有操作结束
wait
# 删除原文件
rm **/*.(jpg|png|PNG|jpeg|JPEG|gif|GIF)
# 避免覆盖同名文件
rename .jpg.JPG .jpg **/*.JPG
rename .png.JPG _p.jpg **/*.JPG
rename .PNG.JPG _p.jpg **/*.JPG
rename .jpeg.JPG _e.jpg **/*.JPG
rename .JPEG.JPG _e.jpg **/*.JPG
rename .gif.JPG _g.jpg **/*.JPG
rename .GIF.JPG _g.jpg **/*.JPG총결산
본 고 는 비교적 실 용적 인 zsh 스 크 립 트 를 설명 하 였 으 며, 추 후 에는 더 많은 것 을 보충 할 수 있 습 니 다.
역 사 를 갱신 하 다
2017.09.13: '인 스 턴 스 7', '인 스 턴 스 8' 과 '인 스 턴 스 9' 를 추가 합 니 다.
본 고 는 더 이상 업데이트 되 지 않 습 니 다. 전체 시 리 즈 는 여기 서 유지 보 수 를 업데이트 합 니 다. github.com/goreliu/zshguide
유 료 로 Windows, Linux, Shell, C, C++, AHK, Python, JavaScript, Lua 등 분야 관련 문 제 를 해결 하고 유연 하 게 가격 을 책 정 합 니 다. 상담 을 환영 합 니 다. 위 챗 ly 50247.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
💤 WSL의 Zsh다른 점은 철자 수정 및 재귀 경로 확장과 같은 몇 가지 추가 기능과 함께 플러그인 및 테마에 대한 지원입니다. Windows 10 또는 11 WSL 또는 WSL2 사용되는 터미널 명령은 Ubuntu/Debian 기...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.