文件检查多个文件名

文件检查多个文件名

我有一个场景,其中所有文件模式都放置在文本文件中。现在我需要编写一个 shell 脚本来读取文本文件中存在的每个文件模式名称,并检查它是否存在于目录中。最后应将输出写入日志文件。

#!/bin/ksh
file="/usr/opt/filenames.txt"
mondir=/home/pavan
while read line
do
        # display list of files with the pattern in the monitoring directory
filename=$line
ls -lrt $mondir/$filename*
done <"$file"

上面的代码列出了文件。但我还需要打印计数(每个文件模式名称的文件数。

答案1

#!/bin/ksh -
file="/usr/opt/filenames.txt"
mondir=/home/pavan
IFS=
while read -r filepattern
do
  set -- "$mondir"/$filepattern*
  if [ "$#" -eq 1 ] && [ ! -e "$1" ] && [ ! -L "$1" ]; then
    printf '%s\n' "$filepattern: 0"
  else
    printf '%s\n' "$filepattern: $#"
    ls -lrtd -- "$@"
  fi
done <"$file"

ksh,就像 Bourne shell 有一个错误特性,当模式不匹配时,它会扩展到自身。上面,我们使用存在性测试 ( [ -e "$1" ]) 来检查是否处于不匹配模式的情况,但请注意,它并不是万无一失的。

例如,对于filepattern='[a-z]',如果[a-z]*不匹配任何文件,则未展开的模式 ( [a-z]*) 实际上可能引用被调用的文件[a-z]*(与模式不匹配)。

如果您ksh基于最新版本的ksh93,您可以使用以下方法修复它:

#!/bin/ksh -
file="/usr/opt/filenames.txt"
mondir=/home/pavan
IFS=
while read -r filepattern
do
  set -- "$mondir"/~(N)$filepattern*
  printf '%s\n' "$filepattern: $#"
  [ "$#" -eq 0 ] || ls -lrtd -- "$@"
done <"$file"

~(N)会导致 glob 在不匹配时扩展为空(如N的 glob 限定符zsh)。

相关内容