如何在不使用长正则表达式字符串的情况下动态地在循环中使用多个Bash参数?

时间:2017-03-06 09:09:37

标签: bash

我有一个包含以下文件的目录:

  • file1.jpg
  • file2.jpg
  • file3.jpg
  • file1.png
  • file2.png
  • file3.png

我有一个名为filelist的bash函数,它看起来像这样:

filelist() {

  if [ "$1" ]
    then
      shopt -s nullglob
      for filelist in *."$@" ; do
      echo "$filelist" >> created-file-list.txt;
      done
      echo "file created listing: " $@;
    else
      filelist=`find . -type f -name "*.*" -exec basename \{} \;`
      echo "$filelist" >> created-file-list.txt
      echo "file created listing: All Files";
  fi

}

目标:能够输入我想要的多个参数,例如filelist jpg png,并创建一个文件列表,其中只包含我用作参数的扩展名的文件列表。因此,如果我输入filelist jpg,它只会显示包含.jpg的文件列表。

目前:由于$@,我的代码可以很好地使用一个参数,但是当我同时使用jpg和png时,它会创建以下列表

  • file1.jpg
  • file2.jpg
  • file3.jpg
  • PNG

看起来我的for循环只运行一次而且只使用第一个参数。我的怀疑是我需要计算多少个参数并在每个参数上运行循环。

一个明显的解决方法是创建一个像(jpg|png|jpeg|html|css)这样的长正则表达式检查,以及一个人们可以想到要输入的所有不同扩展名。这并不理想,因为我希望其他人可以自由地输入他们的文件扩展名而不会破坏它,如果他们输入我在我的正则表达式中没有识别的文件扩展名。动态是关键。

2 个答案:

答案 0 :(得分:1)

您可以重写您的函数,如下所示 - 只需遍历每个扩展名并将匹配文件列表附加到输出文件中:

filelist() {
  if [ $# -gt 0 ]; then
    shopt -s nullglob
    for ext in "$@"; do
      printf '%s\n' *."$ext" >> created-file-list.txt
      echo "created listing for extension $ext"
    done
  else
    find . -type f -name "*.*" -exec basename \{} \; >> created-file-list.txt
    echo "created listing for all files"
  fi
}

您可以调用您的函数:

filelist jpg png

答案 1 :(得分:0)

试试这个

#!/bin/bash

while [ -n "$1" ]
  do
    echo "Current Parameter: $1 , Remaining $#"
    #Pass $1 to some bash function or do whatever
    shift
done

使用shift,你可以通过阅读$1变量来移动args并获得下一个。

请参阅man bash了解转移的内容。

  

shift [n]

     

来自n + 1 ...的位置参数被重命名为$ 1. ....数字$#表示的参数由$# - n + 1表示   未设置。必须                 是一个小于或等于$#的非负数。如果n为0,则不更改任何参数。如果没有给出n,则假设为   如果是                 大于$#,位置参数不会改变。如果n大于,则返回状态大于零   $#或更少                 比零;否则为0。

或者您可以按如下方式进行迭代

for this in "$@"
 do
   echo "Param = $this";
done