我正在尝试创建一个文本文件,其中包含第一行中包含特定字符串的所有日志文件的列表。更具体地说,是SAS日志文件。
目前我有一个简单的脚本,它将在整个系统中搜索“* .log”文件,并将整个列表输出到文本文件中。
有没有办法只输出包含某个字符串的日志文件?
这是当前的命令:
find `pwd` -name "*.log" > sas_log_list.txt
每个SAS日志文件在第一行包含相同的字符串 这个字符串是:
1 SAS系统
所以基本上我想在文件系统中搜索包含上面字符串的日志文件,并将这些文件名输出到文本文件中。
提前致谢, 杰森
答案 0 :(得分:3)
这个问题最困难的部分是仅在第一行内搜索。 我能想到的最准确的一个班轮(为了便于阅读而在这里打破)是:
find . -name '*.log' -type f -readable ! -size 0 \
-exec sed -n '1{/The SAS System/q0};q1' {} \; \
-print
由于sed
语法的模糊性,有些解释依次为:
1{...}
仅针对第一行进行评估。/regex/q0
命令将退出,退出代码为0(成功)(考虑/^regex$/
以使整个行与正则表达式匹配)。q1
将退出并退出1(失败)。 find
使用sed
命令作为谓词,-print
仅当它是真的时使用-size 0
。然而,有一个小问题。显然,如果文件与sed
exit 0
! -size 0
,则会立即find
而不评估其参数。出于这个原因,我们需要-type f
的{{1}}参数。
正如@Brandon Horsley所建议的那样,-readable
会产生更少的错误,而我们在此时也可以验证该文件是{{1}}。
答案 1 :(得分:0)
find `pwd` -name "*.log" -exec grep "The SAS System" {} \;
或
find \`pwd\` -name "\*.log" | grep -i "the sas system"
答案 2 :(得分:0)
除非我弄错了,否则你不需要拨打pwd
。我想这会得到你想要的东西。您可以在grep上使用-l标志来获取文件名而不是匹配的行。
find . -name "*.log" -exec grep -l "The SAS System" {} \; > sas_log_list.txt
答案 3 :(得分:0)
我试图通过只读取每个文件的第一行来使事情变得更快。这将打印出与模式匹配的文件名。
( IFS=$'\n' ; for f in $(find `pwd` -name "*log" -type f ) ; do
head -n 1 "$f" | grep -q "The SAS System" && echo "$f"
done )
更新1 :使用one of the techniques提供的Charles Duffy编辑处理包含空格的路径名。我无法使用find -exec .. +
表达式,因为{}
不能出现多次。感谢ghostdog74和Telemachus
更新2 :添加完整路径名和上次修改时间
( IFS=$'\n' ; for f in $(find . -name "*log" -type f ) ; do
head -n 1 "$f" | grep -q "The SAS System" && echo $(readlink -f "$f") $(stat -c %y "$f")
done )
答案 4 :(得分:0)
bash 4
shopt -s globstar
shopt -s nullglob
for logfile in **/*.log
do
read firstline<"$logfile"
case "$firstline" in
*"The SAS System"*) echo "$logfile" >> sas_log_list.txt
esac
done