bash脚本不过滤

时间:2018-03-14 21:33:12

标签: bash shell

我希望这是一个简单的问题,因为我之前从未做过shell脚本。我试图从结果列表中过滤某些文件。当脚本执行并打印出文件列表时,它不会过滤掉我不想要的文件。感谢您提供的任何帮助!

#!/bin/bash

# Purpose: Identify all *md files in H2 repo where there is no audit date
#
#
#
# Example call: no_audits.sh
#
# If that call doesn't work, try ./no_audits.sh
#
# NOTE: Script assumes you are executing from within the scripts directory of
#       your local H2 git repo.
#
# Process:
# 1) Go to H2 repo content directory (assumption is you are in the scripts dir)
# 2) Use for loop to go through all *md files in each content sub dir
#    and list all file names and directories where audit date is null
#

#set counter
count=0

# Go to content directory and loop through all 'md' files in sub dirs
cd ../content

FILES=`find .  -type f -name '*md' -print`

for f in $FILES
do

   if [[ $f == "*all*" ]] || [[ $f == "*index*" ]] ;
   then
      # code to skip
      echo " Skipping file:  " $f
      continue
   else
   # find audit_date in file metadata
   adate=`grep audit_date $f`

   # separate actual dates from rest of the grepped line
   aadate=`echo $adate | awk -F\' '{print $2}'`

   # if create date is null - proceed
      if [[ -z "$aadate" ]] ;
      then

         # print a list of all files without audit dates
         echo "Audit date: " $aadate " " $f;
         count=$((count+1));
      fi
   fi
done
echo $count " files without audit dates "

2 个答案:

答案 0 :(得分:2)

首先,要解决当前问题:

[[ $f == "*all*" ]]

仅当 f 的确切内容为字符串*all*时才为真 - 将通配符作为文字字符。如果要检查子字符串,则不应引用星号:

[[ $f = *all* ]]

...是一种更好的练习解决方案。 (注意使用=而不是== - 这不是必需的,但这是一个很好的习惯,因为POSIX test command仅被指定为允许= }作为字符串比较运算符;如果按习惯写[ "$f" == foo ],可以在严格遵守/bin/sh的平台上出现意外故障。

尽管如此,这个旨在遵循最佳实践的脚本的实现可能看起来更像是:

#!/usr/bin/env bash
count=0
while IFS= read -r -d '' filename; do
  aadate=$(awk -F"'" '/audit_date/ { print $2; exit; }' <"$filename")
  if [[ -z $aadate ]]; then
    (( ++count ))
    printf 'File %q has no audit date\n' "$filename"
  else
    printf 'File %q has audit date %s\n' "$filename" "$aadate"
  fi
done < <(find . -not '(' -name '*all*' -o -name '*index*' ')' -type f -name '*md' -print0)
echo "Found $count files without audit dates" >&2

注意:

  • 任意文件名列表都不能存储在单个bash字符串中(因为所有可能用于确定名字结束位置和下一个名称开头的字符都可能出现在名称本身中)。相反,一次读取一个NUL分隔的文件名 - 用find -print0发出,用IFS= read -r -d ''读取;这在[BashFAQ#1]中讨论过。
  • 可以在find内部过滤掉不需要的名称。
  • 无需使用awk预处理grep的输入,因为awk能够自行搜索输入文件。
  • < <(...)用于避免BashFAQ #24中的行为,其中传送到while循环的内容导致该循环中设置或修改的变量在退出后变为不可用。
  • 处理未知文件名时,
  • printf '...%q...\n' "$name"echo "...$name..."更安全,因为printf将发出可准确表示这些名称的可打印内容,即使它们包含不可打印的字符或字符,直接发送到终端,用于修改该终端的配置。

答案 1 :(得分:0)

没关系,我在这里找到了答案:

bash script to check file name begins with expected string

我尝试了各种版本的通配符/文件名,结果是:

if [[“$ f”== * all.md]] || [[“$ f”== * index.md]];

上面的链接说不要把它们放在引号中,删除引号就行了!