
我有以下目錄結構:
test/
test/1/
test/foo2bar/
test/3/
我想壓縮目錄“test”,不包括子目錄中的所有內容(深度未預先定義),其中包括字串“1”或“2”。在 bash shell 中,我想使用尋找並將其輸出饋送到柏油。我先測試尋找:
find test/ -not -path "*1*" -not -path "*2*"
輸出:
test/
test/3
偉大的。所以我把它與柏油:
find test/ -not -path "*1*" -not -path "*2*" | tar -czvf test.tar.gz --files-from -
輸出:
test/
test/3/
test/1/
test/foo2bar/
test/3/
事實上,「test/1」和「test/foo2bar」都存在於檔案中。如果這些參數不應該出現在 find 輸出中,為什麼要傳遞給 tar?
答案1
為了擴展 @cuonglm 所說的內容,預設tar
是遞歸操作的。如果你給它一個目錄名,它就會歸檔內容該目錄的。
您可以修改find
命令以僅返回檔案名,而不返回目錄...
find test/ -type f -not -path "*1*" -not -path "*2*" |
tar -czvf test.tar.gz --files-from -
您可以使用該--no-recursion
標誌來tar
:
find test/ -not -path "*1*" -not -path "*2*" |
tar -czvf test.tar.gz --no-recursion --files-from -
結果是:
test/
test/3/
該--no-recursion
標誌特定於 GNU tar。如果您正在使用其他功能,請查閱相應的手冊頁以查看是否有類似的功能可用。
請注意,您的find
命令將排除文件包含1
或2
在路徑和目錄中。
答案2
使用 GNU tar,您還可以使用該--exclude
選項根據名稱排除檔案。
$ tar --exclude "*1*" --exclude "*2*" -cvf foo.tar test/
test/
test/3/
還有-X
or --exclude-from
which 需要一個檔案來讀取排除模式。
儘管 as find -not -path "*1*"
,這也會排除名稱包含1
或的檔案2
。僅跳過目錄其名稱與模式匹配,使用find -prune
和tar --no-recursion
:
$ touch test/3/blah.1
$ find test/ -type d \( -name "*1*" -o -name "*2*" \) -prune -o -print |
tar cvf test.tar --files-from - --no-recursion
test/
test/3/
test/3/blah.1
(至少 GNU tar 和 FreeBSD tar 有--no-recursion
)