bash脚本未进行筛选
我希望这是一个简单的问题,因为我以前从未做过shell脚本。我正在尝试从结果列表中筛选某些文件。当脚本执行并打印文件列表时,它不会过滤掉我不想要的文件。谢谢你能提供的任何帮助bash脚本未进行筛选,bash,shell,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_
#!/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 "
首先,为了解决眼前的问题:
[[ $f == "*all*" ]]
仅当f的确切内容是字符串*all*
——且通配符为文字字符时,才为true。如果要检查子字符串,则不应引用星号:
[[ $f = *all* ]]
…是一个更好的实践解决方案。(注意使用=
而不是=
——这不是必要的,但是一个好习惯,因为只指定=
作为字符串比较运算符;如果一个人习惯性地编写[“$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
#/usr/bin/env bash
计数=0
而IFS=read-r-d“”文件名;做
aadate=$(awk-F“'”/audit_date/{print$2;exit;}'首先,解决眼前的问题:
[[ $f == "*all*" ]]
仅当f的确切内容为字符串*all*
——且通配符为文字字符时才为真。如果要检查子字符串,则不应引用星号:
[[ $f = *all* ]]
…是一个更好的实践解决方案。(注意使用=
而不是=
——这不是必要的,但是一个好习惯,因为只指定允许=
作为字符串比较运算符;如果编写[“$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
!/usr/bin/env bash
计数=0
当IFS=read-r-d“”文件名时,执行以下操作
aadate=$(awk-F“'”/audit_date/{print$2;exit;}'
我尝试了各种版本的通配符/文件名,结果是:
如果[[“$f”===*all.md]| |[[“$f”===*index.md]]
上面的链接说不要把它们放在引号里,删除引号就成功了!没关系,我在这里找到了答案:
我尝试了各种版本的通配符/文件名,结果是:
如果[[“$f”===*all.md]| |[[“$f”===*index.md]]
上面的链接说不要把它们放在引号中,删除引号就可以了!添加预期的输出…在构建StackOverflow问题时,请尝试创建生成特定问题的最短代码。在这种情况下,可以通过使用bash-x yourscript
跟踪代码,观察它运行的每个命令来完成找到第一个不符合你期望的命令,只要求一个命令。也请参阅关于构建A的文档。也就是说,这里也有一些反模式。考虑运行你的代码;并且也看到/ /你应该遵循的做法。任何文件名都包含空格;可以解释为globs;等等。直接的问题是[[$f==“*all*”]]
中的引号意味着您只排除名为*all*
的文件,而不排除名为all
的文件。对于后者,它将是[$f=*all*]]
,不带引号。是的,应该使用更好的find
表达式,而不是在bash中进行后处理。添加预期输出…在生成StackOverflow问题时,请尝试创建生成特定问题的最短代码。在这种情况下,可以通过使用bash跟踪代码来完成X-YuScript ,查看它运行的每个命令,找到不符合您预期的第一个命令,只询问一个命令。也请参阅关于构建A的文档。也就是说,这里也有许多反模式。考虑运行您的代码;并且也看到/ /并且,您应该实践FO。下面,。如果任何文件名包含空格,当前代码将表现不好;可以解释为globs;等等。直接的问题是,[[$f==“*all*”]
中的引号意味着您只排除名为*all*
的文件,而不是名称中包含all
的文件。对于后者,它将是[[$f=*all*]]
,不带引号。是的,这应该使用更好的find
表达式来完成,而不是在bash中进行任何后处理。@MarkSetchell,是的,将文件名作为单独的参数传递是完全合法的。参数是这样,我们可以在不带--
符号的情况下处理不寻常的文件名…但是当这些名称来自find
时,它们的前缀肯定是/
,并且严格遵循POSIX的命令行解析器无论如何都会将第一个位置参数之后的任何内容视为位置参数,因此这两种方法都是完全正确的(我倾向于谨慎,因为GNU的命令行解析器通常不严格遵守POSIX).@MarkSetchell,是的,将文件名作为一个单独的参数传递是完全合法的。这个参数是这样的,即使是不寻常的文件名,我们也可以不使用--
符号来处理…但是当这些名称来自find
时,保证它们的前缀是//code>,并且严格的POSIX compliant命令行解析器会将第一个位置参数之后的任何内容视为位置参数,无论如何,这两种方法都是非常好的(我倾向于谨慎,因为GNU的命令行解析器通常不严格遵守POSIX)。我相信,在发布此答案之前约20分钟也发现了这个问题。