【问题标题】:Shell Script working with multiple files [duplicate]使用多个文件的 Shell 脚本 [重复]
【发布时间】:2018-03-07 21:19:46
【问题描述】:

我有以下代码:

#!/bin/bash

filename=$1
file_extension=$( echo $1 | cut -d. -f2 )
directory=${filename%.*}

if [[ -z $filename ]]; then
    echo "You forgot to include the file name, like this:"
    echo "./convert-pdf.sh my_document.pdf"
else
    if [[ $file_extension = 'pdf' ]]; then
        [[ ! -d $directory ]] && mkdir $directory
        convert $filename -density 300 $directory/page_%04d.jpg
    else
        echo "ERROR! You must use ONLY PDF files!"
    fi
fi

而且运行良好!

我想创建一个可以执行以下操作的脚本:./script.sh *.pdf

我该怎么做?使用星号。

感谢您的宝贵时间!

【问题讨论】:

    标签: linux shell


    【解决方案1】:

    首先意识到shell 会将*.pdf 扩展为参数列表。这意味着你的 shell 脚本永远不会看到*。相反,它会得到一个参数列表。

    您可以使用如下结构:

    #!/bin/bash
    
    function convert() {
      local filename=$1
      # do your thing here
    }
    
    if (( $# < 1 )); then
      # give your error message about missing arguments
    fi
    while (( $# > 0 )); do
      convert "$1"
      shift
    done
    

    它的作用是首先将您的功能包装在一个名为convert 的函数中。然后对于主代码,它首先检查传递给脚本的参数的数量,如果它小于 1(即没有),则给出应该传递文件名的错误。然后你进入一个while循环,只要有剩余的参数就会执行。您传递给转换函数的第一个参数执行您的脚本已经执行的操作。然后执行shift 操作,它的作用是丢弃第一个参数,然后将所有剩余参数“左”移一个位置,即$2 现在是$1,@987654328 @ 现在是 $2 等。通过在 while 循环中执行此操作直到参数列表为空,您将遍历所有参数。

    顺便说一下,您的初始分配有一些问题:

    • 你不能假设文件名有扩展名,你的代码可以匹配某个目录路径中的点。
    • 您的目录分配似乎在 .而不是 /
    • 如果没有给出绝对或相对路径,您的目录分配将包含文件名,即只有一个裸文件名
    • ...

    我认为你应该多花点时间在健壮性上

    【讨论】:

    • convert "$1",而不是 convert($1)。并避免使用 function 关键字——它使代码无缘无故地与 POSIX 基线 shell 不兼容(不像 bashisms,如 (( )),它实际上增加了价值)。
    • @CharlesDuffy 谢谢,似乎一次使用了太多语言......更正了函数调用。我不太同意 function 关键字,它让那些不太熟悉 shell 脚本的人更清楚地知道正在定义一个函数,而且因为它是一个实际的 bash 脚本,所以不兼容是一个有争议的问题。我应该明确它是一个 bash 脚本,但是我会添加适当的 hashbang。
    • 顺便说一句,使用: 而不是# 作为占位符的意义在于,即使没有人填写占位符,它也会使您的代码在语法上有效。只有条件或循环主体中的注释不会解析。
    • Re:function 关键字,选择在示例中使用它使得可移植语法在新手中不太常见,这是一个自我实现的预言。
    【解决方案2】:

    将您的代码包装在一个循环中。也就是说,而不是:

    filename=$1
    : code goes here
    

    使用:

    for filename in "$@"; do
      : put your code here
    done
    

    【讨论】:

    • 社区 wiki 以避免从回答已知重复项中获取代表
    猜你喜欢
    • 2021-11-30
    • 1970-01-01
    • 2018-06-09
    • 2016-03-14
    • 1970-01-01
    • 2013-05-02
    • 2019-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多