iT邦幫忙

0

如何用bat、shell script 搜尋關鍵字資料夾,最新檔案

各位前輩好,
想請問如何用bat或powershell(Windows)及shell script(Linux)寫出
能搜尋資料夾名稱如:用戶名(不固定)\日誌(固定)\ 內最新的檔案,
並含完整路徑轉出成txt,例如
D:\backup\Vicent Li\日誌\下有多個backup 2018-xx-xx xxx.log
D:\backup\Allen Huang\日誌\下有多個backup 2018-xx-xx xxx.log
D:\backup\Chris Wang\日誌\下有多個backup 2018-xx-xx xxx.log

想輸出每個用戶下最近產出的檔名,得到如下
D:\backup\Vicent Li\日誌\backup 2018-08-29 130002.975.log
(表示最近一次備份日為8/29)
D:\backup\Allen Huang\日誌\backup 2018-08-28 100001.100.log
(表示最近一次備份日為8/28)
D:\backup\Chris Wang\日誌\backup 2018-07-28 110001.100.log
(表示最近一次備份日為7/28)
這樣就可知道Chris Wang已經超過一個月沒備份日誌了,需檢查備份排程
感謝幫忙。
文件系統有Windows也有Linux

我的想法是抓出D:\backup\變數\日誌\ 底下最新檔案
只是不知道linux windows 那變數怎麼去抓backup底下資料夾名稱,轉成陣列,一個個執行並輸出

0
fuzzylee1688
iT邦新手 2 級 ‧ 2018-08-29 14:43:13

window 可用以下指令進行搜尋: dir /s 複製

vicentli iT邦新手 3 級 ‧ 2018-08-30 16:26:08 檢舉

謝謝,已用powershell處理

0
看更多先前的回應...收起先前的回應...
vicentli iT邦新手 3 級 ‧ 2018-08-30 10:31:27 檢舉

謝謝,請問一下,我想把ls找到的資料夾轉成陣列,可以怎麼打?感謝

array=($(ls -d */))
vicentli iT邦新手 3 級 ‧ 2018-08-30 16:30:59 檢舉

謝謝,目前測試,同一目錄如Vicent Li 中間有空格,會存成2個索引,有無解決法,感謝。

x=($(find . -maxdepth 1 -type d -printf '%f\n'))
vicentli iT邦新手 3 級 ‧ 2018-08-30 17:37:48 檢舉

感謝你的幫忙,嘗試執行
find . -maxdepth 1 -type d -printf '%f\n' 結果如下
.
Vicent Li
Allen Huang
嘗試寫成bash
x=($(find . -maxdepth 1 -type d -printf '%f\n'))
echo ${x[0]}
echo ${x[1]}
echo ${x[2]}
echo ${x[3]} 來偵錯,輸出如下
.
Vicent
Li
Allen

Vicent與Li被array分開了

vicentli iT邦新手 3 級 ‧ 2018-08-30 17:47:07 檢舉

搞定了 加入IFS=$'\n',謝謝 跟著鄉民看熱鬧

寫完再整個分享出來吧,或許有人用得到
/images/emoticon/emoticon13.gif

vicentli iT邦新手 3 級 ‧ 2018-08-31 12:34:11 檢舉

如下
IFS=$'\n'
declare -a User=($(ls -l |grep "^d" |awk '{print $10" "$11}'))
let UserLength=${#User[@]}-2 去掉arry尾2個不相干資料夾
echo '' > log
for ((i=0; i<$UserLength; i++))
do
Path=${User[$i]}
echo ${User[$i]} >> log
ls -lt $Path/日志 |sed -n 2p >> log
done

0
froce
iT邦大師 3 級 ‧ 2018-08-29 15:16:14

powershell

Get-ChildItem 「路徑」 | sort LastWriteTime | select -last 1
看更多先前的回應...收起先前的回應...
vicentli iT邦新手 3 級 ‧ 2018-08-29 17:09:53 檢舉

謝謝回覆。想請問路徑的問題,怎麼把backup下的資料夾名稱轉成陣列$用戶[名0,名1,名2],然後用powershell 去迴圈執行
Get-ChildItem 用戶[i]\日誌\ | sort LastWriteTime | select -last 1 > test.txt
Get-ChildItem 用戶[i++]\日誌\ | sort LastWriteTime | select -last 1 >> test.txt

froce iT邦大師 3 級 ‧ 2018-08-29 18:42:50 檢舉

powershell 可以用string format啊。

$a = "test {0} test {1}"
$b = @('b', 'c')
write-host($a -f $b)
vicentli iT邦新手 3 級 ‧ 2018-08-30 13:51:57 檢舉

感謝提供的一些指導,powershell部分寫出來了
Get-ChildItem -Exclude 日誌,歷史版本,log.ps1 | Select-Object Name > d:\user.txt
$User=(Get-Content d:\user.txt)
$UserTrim=$User.Trim()
$len = $UserTrim.Length-3
Clear-Content D:\temp.txt
for($i=3;$i -le $len;$i++){
$path = join-path -path $UserTrim[$i] -childpath 日誌
Get-ChildItem $path | sort LastWriteTime | select -last 1 >> D:\temp.txt
}
Get-Content D:\temp.txt | ? {$_.trim() -ne "" } | set-content D:\log.txt

原本想for裡1行命令就好,但若在路徑裡加上變數,例如改成
Get-ChildItem D:\backup\$UserTrim[$i]\日誌 | sort LastWriteTime | select -last 1 >> D:\temp.txt
會無法執行,不知道怎麼處理只好多加1條,先把整串路徑轉為變數

marlin12 iT邦新手 2 級 ‧ 2018-08-31 00:35:16 檢舉

為何要寫出去user.txt和temp.txt,然後又讀回來?
為何要去掉頭、尾的3個項目?

$subDirs = Get-ChildItem "D:\backup" | ?{ $_.PSIsContainer } | %{ $_.FullName }

$outputFile = "D:\report.txt"

Clear-Content $outputFile

foreach($sub in $subDirs) {
    Get-ChildItem $($sub + "\日誌") -filter "*.log" | sort LastWriteTime | select -last 1 -expand FullName >> $outputFile 
}
vicentli iT邦新手 3 級 ‧ 2018-08-31 01:33:15 檢舉

去頭是有三行空白、標頭分隔符不需要帶入,去尾是有三個空白行。其實我是拼拼湊湊爬文出來的,覺得先求有再求好,週五要完成第一版,目前還沒寫好linux的。很感謝你提供較好的寫法,我完全門外漢,只是有一點點寫程式的邏輯

vicentli iT邦新手 3 級 ‧ 2018-08-31 01:39:48 檢舉

清掉

marlin12 iT邦新手 2 級 ‧ 2018-09-01 16:40:51 檢舉

上面的程式還有2個隱懮,如果那個用戶的[日誌]資料夾不存在或者他沒有log文件,他的資料就不會被記錄下來。因此,程式應該加上相關的檢測,如下:

#列出在"D:\backup"裏全部的子資料夾的全路徑
$subDirs = Get-ChildItem "D:\backup" | ?{ $_.PSIsContainer } | %{ $_.FullName }

$results = @()		#陣列變數

foreach($sub in $subDirs) {
	$sub += "\日誌"

	if (Test-Path $sub) {	#資料夾存在嗎?
		#列出在$sub裏全部的log文件
		$logFiles = Get-ChildItem $sub -filter "*.log"

		if ($logFiles.Length -gt 0) {	 #有log文件嗎?
			#找出在$sub裏最新的log文件的全路徑
			$results += $logFiles | sort LastWriteTime | select -last 1 -expand FullName
		} else {
			$results += $sub + " [警告:沒有log文件]"
		}
	} else {
		$results += $sub + " [警告:資料夾不存在]"
	}
}

#將結果放進"D:\report.txt"文件裏
Set-Content "D:\report.txt" -value $results
vicentli iT邦新手 3 級 ‧ 2018-09-01 17:35:32 檢舉

感謝協助,我後來把使用者與日誌輸出分開兩行,讓沒有目錄、或目錄是空的就只顯示使用者名稱,不過沒有你寫得這麼好!謝謝提供參考

0
antonio
iT邦新手 5 級 ‧ 2018-08-31 13:17:49
#!/bin/bash
WorkDir="/backup"
ReportFile="/tmp/report`date +%Y%m%d_%H%M%S`.txt"
find  ${WorkDir} -type d -name "日誌"> /tmp/test.txt
echo "[`date +%Y-%m-%d\ %H:%M:%S`] Process Start">> ${ReportFile}
exec < /tmp/test.txt
while read -r line
do
        ls -alht ${line}/*.log|grep -v total|head -n 1 >> ${ReportFile}
done
echo "[`date +%Y-%m-%d\ %H:%M:%S`] Process End">> ${ReportFile}

這樣就可以幫你列出最近的清單

vicentli iT邦新手 3 級 ‧ 2018-08-31 18:03:56 檢舉

非常感謝!我研究一下

我要發表回答

立即登入回答