我有一个脚本,它与多个日志文件中的目录中的字符串相匹配,如下所示:
#!/bin/sh
# Collect Customer ID as input
read -p "Enter Customer ID: " custid
echo "Searched customer ID $custid found in following logs: "
# Find the customer id as string in specified directory
find /usr/local/tomcat9/logs/ -type f -exec grep -l "$custid" {} \;
这将输出包含搜索字符串的日志文件列表。例如:
Enter Customer ID: 2001NM-100313
Searched customer ID 2001NM-100313 found in following logs:
/usr/local/tomcat9/logs/localhost_access_log.2017-10-04.txt
/usr/local/tomcat9/logs/localhost_access_log.2017-07-11.txt
/usr/local/tomcat9/logs/localhost_access_log.2017-11-02.txt
/usr/local/tomcat9/logs/localhost_access_log.2017-09-11.txt
/usr/local/tomcat9/logs/localhost_access_log.2017-08-09.txt
/usr/local/tomcat9/logs/localhost_access_log.2017-06-11.txt
我想要这个输出作为列表,如下所示:
1. /usr/local/tomcat9/logs/localhost_access_log.2017-10-04.txt
2. /usr/local/tomcat9/logs/localhost_access_log.2017-07-11.txt
3. /usr/local/tomcat9/logs/localhost_access_log.2017-11-02.txt
4. /usr/local/tomcat9/logs/localhost_access_log.2017-09-11.txt
5. /usr/local/tomcat9/logs/localhost_access_log.2017-08-09.txt
6. /usr/local/tomcat9/logs/localhost_access_log.2017-06-11.txt
它会要求输入数字 1/2/3/4/5/6,这将打开该编号的文件,即;如果我按 4 它会发送命令
vim /usr/local/tomcat9/logs/localhost_access_log.2017-09-11.txt
并且将在整个文件中搜索字符串“2001NM-100313”。
我的目标是从日志文件中读取包含此字符串的整行(可能有多个行包含该字符串),可能有多个日志文件包含此字符串和多个日期,我需要选择任何带日期的文件并阅读日志。
答案1
只需使用select
(bash
内置)。
$ help select
select: select NAME [in WORDS ... ;] do COMMANDS; done
The WORDS are expanded, generating a list of words. The
set of expanded words is printed on the standard error, each
preceded by a number. If `in WORDS' is not present, `in "$@"'
is assumed. The PS3 prompt is then displayed and a line read
from the standard input. If the line consists of the number
corresponding to one of the displayed words, then NAME is set
to that word. If the line is empty, WORDS and the prompt are
redisplayed. If EOF is read, the command completes. Any other
value read causes NAME to be set to null. The line read is saved
in the variable REPLY. COMMANDS are executed after each selection
until a break command is executed.
$
所以你想要的代码可能是:
read -p 'Enter Customer ID: ' custid
select f in $(find /usr/local/tomcat9/logs -type f -exec grep -q -e "$custid" {} \; -print); do
vim "$f"
done
请注意,如果您的文件名包含空格,则会中断。也可以看看:
但是,如果您select
直接从 调用内置函数find
,这将轻松处理空格。所以下面的实际上更好在所有情况下我都能想到:
read -p 'Enter customer ID: ' custid
find /usr/local/tomcat9/logs -type f -exec grep -qe "$custid" {} \; -exec bash -c '
select f; do vim "$f"; done' find-sh {} +
答案2
阅读你的问题提醒我总是想要一个简单的脚本,这样我可以更轻松地在文件中搜索特定字符串,然后查看包含该字符串的文件之一。根据您的脚本和 saga 使用数组的建议,我创建了我的脚本并完成了您的脚本。 :)
请注意:这个脚本是/bin/bash,而不是/bin/sh,因为我不知道如何让数组在/bin/sh中工作...
你的脚本:
#!/bin/bash
# Collect Customer ID as input
read -p "Enter Customer ID: " custid
echo "Searched customer ID $custid found in following logs: "
# Find the customer id as string in specified directory
arr=( $(find /usr/local/tomcat9/logs/ -type f -exec grep -l "$custid" {} \; | sort -r) )
if [ ${#arr[@]} -eq 0 ]; then
echo "No matches found."
else
arr+=('Quit')
select opt in "${arr[@]}"
do
case $opt in
"Quit")
break
;;
*)
vim $opt
break
;;
esac
done
fi
编辑:虽然上面的脚本对于原始问题来说可以完美工作,但我已经建立在通配符的答案之上,因此我的脚本可以处理带有空格的文件并提供各种工具打开选定的文件。
我的脚本:
#!/bin/bash
# Find string in files of given directory (recursively)
read -p "Enter search string: " text
read -p "Enter directory: " directory
#arr=( $(find $directory -type f -exec grep -l "$text" {} \; | sort -r) )
#find $directory -type f -exec grep -qe "$text" {} \; -exec bash -c '
file=$(find $directory -type f -exec grep -qe "$text" {} \; -exec bash -c 'select f; do echo $f; break; done' find-sh {} +;)
if [ -z "$file" ]; then
echo "No matches found."
else
echo "select tool:"
tools=("nano" "less" "vim" "quit")
select tool in "${tools[@]}"
do
case $tool in
"quit")
break
;;
*)
$tool $file
break
;;
esac
done
fi