我希望这是一个简单的问题,因为我之前从未做过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 "
答案 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
注意:
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]];
上面的链接说不要把它们放在引号中,删除引号就行了!