Shell-Script
使用 shell 工具 awk 編輯 fslint 的輸出 |grep |sed
任務是根據一組規則將此文本文件(實用程序的輸出
fslint
)轉換為 bash 腳本,其中包含rm
要刪除的重複文件的命令行和要保留的文件的註釋行。規則基本上是說:只刪除特定目錄中的重複文件。
目標是清理多年來在多個作業系統(Mac OS X、Windows、Linux)上積累的大約 1 TB 的重複數據。所有數據都已復製到 Linux 驅動器。
#3 x 697,612,024 (1,395,236,864) bytes wasted /path/to/backup-100425/file_a.dat /another/path/to/backup-disk-name/171023/file_a.dat /yet/another/path/to/labs data/some/path/file_a.dat #4 x 97,874,344 (293,634,048) bytes wasted /path/to/backup-100425/file b.mov /another/path/to/backup-140102/file b.mov /backup-120708/Library/some/path/file b.mov /some/other/path/to/backup-current/file b.mov #2 x 198,315,112 (198,316,032) bytes wasted /path/to/backup-100425/file_c.out /another/path/to/backup-disk-name/171023/file_c.out
第一行表示有 3 個相同的副本,
file_a.dat
接下來的 3 行列出了它們的路徑。理想情況下,應在此處刪除 2 個副本。帶有 6 位數字的目錄(YYMMDD 格式的日期)就是我所說的歷史備份目錄。將按此順序應用於每組相同文件的規則是:
- 如果文件位於包含目錄的路徑中
Library
,請保留它。- 如果文件在
labs data
or中backup-current
,請保留它,並刪除歷史備份目錄中的所有重複項。- 如果文件位於歷史備份目錄中,請將文件保留在最新的備份目錄中,並刪除較舊的副本。
- 否則保留文件。
這是所需的輸出:
#!/bin/bash #3 x 697,612,024 (1,395,236,864) bytes wasted rm '/path/to/backup-100425/file_a.dat' rm '/another/path/to/backup-disk-name/171023/file_a.dat' #/yet/another/path/to/labs data/some/path/file_a.dat #4 x 97,874,344 (293,634,048) bytes wasted rm '/path/to/backup-100425/file b.mov' rm '/another/path/to/backup-140102/file b.mov' #/backup-120708/Library/some/path/file b.mov #/some/other/path/to/backup-current/file b.mov #2 x 198,315,112 (198,316,032) bytes wasted rm '/path/to/backup-100425/file_c.out' #/another/path/to/backup-disk-name/171023/file_c.out
我對 shell 工具 awk、grep 和 sed 不是很熟悉,在閱讀了這個文章後,我意識到我的初稿在概念上是錯誤的,“一個天真的翻譯什麼
$$ I $$可以用像 C" 這樣的命令式語言來做。 事實上,我們在這里處理的不是文件,而是一個文件的內容。
在這種情況下使用 shell 腳本是否合適?
如果是的話,一個高效的腳本會是什麼樣子?
**編輯:**在閱讀了@Ed的答案和程式碼後,我試圖澄清任務和要求,完美地解決了這個問題。
考慮到我願意投入多少時間來嘗試,我不明白你的要求列表,但這裡有一個腳本來分類和列印你似乎感興趣的文件類型,希望你能弄清楚其餘的:
$ cat tst.awk /^#/ { prt(); print; next } { files[$0] } END { prt() } function prt( file, isLibrary, isLabsBack, isNothing) { for (file in files) { if ( file ~ /(^|\/)Library(\/|$)/ ) { isLibrary[file] } else if ( file ~ /(^|\/)(labs data|backup-current)(\/|$)/ ) { isLabsBack[file] } else { isNothing[file] } } for (file in isLibrary) { print "Library", file } for (file in isLabsBack) { print "LabsBack", file } for (file in isNothing) { print "Nothing", file } delete files }
.
$ awk -f tst.awk file #3 x 697,612,024 (1,395,236,864) bytes wasted LabsBack /yet/another/path/to/labs data/some/path/file_a.dat Nothing /another/path/to/backup-disk-name/171023/file_a.dat Nothing /path/to/backup-100425/file_a.dat #4 x 97,874,344 (293,634,048) bytes wasted Library /backup-120708/Library/some/path/file b.mov LabsBack /some/other/path/to/backup-current/file b.mov Nothing /path/to/backup-100425/file b.mov Nothing /another/path/to/backup-140102/file b.mov #2 x 198,315,112 (198,316,032) bytes wasted Nothing /path/to/backup-100425/file_c.out Nothing /another/path/to/backup-disk-name/171023/file_c.out