【问题标题】:rename files with spaces [closed]用空格重命名文件[关闭]
【发布时间】:2012-07-14 20:26:28
【问题描述】:

我想要一个在 linux 上工作的脚本来重命名这种形式的文件,即 Yahoo Babel Fish - Persistent Cross Site Scripting Vulnerability.jpg 到 Yahoo-Babel-Fish-Persistent-Cross-Site-Scripting-Vulnerability.jpg 的形式

它只删除每个空格并用连字符更改它,如果它是两个空格之间的连字符,它只删除空格,就像你在这部分看到的那样 “鱼 - 持久”到“鱼 - 持久”

【问题讨论】:

    标签: linux bash shell rename


    【解决方案1】:

    如果您想处理当前目录中的每个文件,您可以分两行执行此操作:

    for f in *; do mv "$f" "$(echo $f | sed 's/ /-/g')"; done
    for f in *; do mv "$f" "$(echo $f | sed 's/---/-/g')"; done
    

    可能有一种方法可以在一行中完成,但我现在想不出。

    【讨论】:

    • +1:您可以将两个 sed 表达式组合成一个命令:sed -e 's/ /-/g' -e 's/---/-/g'
    • 这看起来是一项相当昂贵的操作,即使只有一个sed。无论如何,您可以使用 herestring 代替 echo 和管道来保存一些操作。
    • 谢谢你们......另一个快速的问题是你推荐我看任何网站或书籍,以便学习在 linux 上编写脚本?
    • @AdrianPronk,甚至:sed 's/[ -]\+/-/g' +1
    【解决方案2】:

    这是一个利用 bash 的数组和 extglob 特性的纯 bash 解决方案:

    shopt -s extglob
    oIFS="$IFS" # save the original IFS
    for file in *.jpg; do # Or whatever pattern you like
        target=( ${file//+(-)/ } ) # Break the filename into an array on spaces, after turning - into space. 
        IFS='-' # Temporarily set the internal field separator into a dash so we can join on dashes.
        mv "$file" "${target[*]}"
        IFS="$oIFS"
    done
    

    【讨论】:

    • 我会选择"${file//+([ -])/-}"
    【解决方案3】:
    for file in *.jpg ; do file2="${file// - /-}"; file2="${file2// /-}"; echo mv "$file" "$file2" ;done
    

    如果这是你想要的,请删除回声。

    【讨论】:

    • 这不适用于名为foo- bar.jpg 的文件。你会得到foo--bar.jpg
    • ...它只删除每个空格并用连字符更改它,如果它是两个空格之间的连字符,它只删除空格...
    【解决方案4】:

    以下是我撰写本文时存在的三个答案的一些基准。随意扩展:

    $ ./rename_bench 
    setting up
    timing ext
    
    real    0m35.453s
    user    0m6.006s
    sys 0m27.417s
    setting up
    timing sed
    
    real    1m17.498s
    user    0m15.223s
    sys 0m56.376s
    setting up
    timing straight
    
    real    0m38.352s
    user    0m6.028s
    sys 0m28.254s
    $ ./rename_bench 
    setting up
    timing ext
    
    real    0m36.234s
    user    0m6.030s
    sys 0m28.270s
    setting up
    timing sed
    
    real    1m16.467s
    user    0m15.277s
    sys 0m56.194s
    setting up
    timing straight
    
    real    0m33.538s
    user    0m5.911s
    sys 0m26.672s
    

    实际的基准测试脚本:

    #!/bin/bash
    
    setup() {
        cd $(mktemp -dt "foo") &&
        touch 'a - '{0..10000}'buzz.jpg'
    }
    ext_rename() {
        shopt -s extglob
        oIFS="$IFS" # save the original IFS
        for file in *.jpg; do # Or whatever pattern you like
            target=( ${file//+(-)/ } ) # Break the filename into an array on spaces, after turning - into space. 
            IFS='-' # Temporarily set the internal field separator into a dash so we can join on dashes.
            mv "$file" "${target[*]}"
            IFS="$oIFS"
        done
    }
    
    sed_rename() {
        for f in *.jpg; do
            mv "$f" "$(sed -e 's/ /-/g' -e 's/---/-/g' <<< "$f")"
        done
    }
    
    straight_rename() {
        for file in *.jpg; do
            file2="${file// - /-}"
            file2="${file2// /-}"
            mv "$file" "$file2"
        done
    }
    
    echo "setting up"
    setup
    echo "timing ext"
    time ext_rename
    echo "setting up"
    setup
    echo "timing sed"
    time sed_rename
    echo "setting up"
    setup
    echo "timing straight"
    time straight_rename
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-20
      • 2012-12-06
      • 1970-01-01
      • 2021-12-21
      • 1970-01-01
      • 2011-09-08
      • 2013-04-05
      • 2019-12-24
      相关资源
      最近更新 更多