我有一個腳本,它與多個日誌檔案中的目錄中的字串相匹配,如下所示:
#!/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