簡體   English   中英

Shell 命令到 tar 目錄,不包括某些文件/文件夾

[英]Shell command to tar directory excluding certain files/folders

是否有一個簡單的 shell 命令/腳本支持從歸檔中排除某些文件/文件夾?

我有一個目錄需要與一個子目錄一起存檔,該子目錄包含許多我不需要備份的非常大的文件。

不完全解決方案:

tar --exclude=PATTERN命令匹配給定的模式並排除那些文件,但我需要忽略特定文件和文件夾(完整文件路徑),否則可能會排除有效文件。

我還可以使用 find 命令創建文件列表並排除我不想存檔的文件並將列表傳遞給 tar,但這只適用於少量文件。 我有幾萬個。

我開始認為唯一的解決方案是創建一個包含要排除的文件/文件夾列表的文件,然后使用 rsync 和--exclude-from=file將所有文件復制到 tmp 目錄,然后使用 tar歸檔該目錄。

有人能想到更好/更有效的解決方案嗎?

編輯: Charles Ma的解決方案效果很好。 最大的問題是--exclude='./folder'必須位於 tar 命令的開頭。 完整命令(首先是 cd,因此備份是相對於該目錄的):

cd /folder_to_backup
tar --exclude='./folder' --exclude='./upload/folder2' -zcvf /backup/filename.tgz .

您可以為 tar 設置多個排除選項,因此

$ tar --exclude='./folder' --exclude='./upload/folder2' -zcvf /backup/filename.tgz .

等會起作用。 確保--exclude源和目標項目之前

您可以使用--exclude for tar 排除目錄。

如果要存檔除/usr之外的所有內容,可以使用:

tar -zcvf /all.tgz / --exclude=/usr

在你的情況下,也許像

tar -zcvf archive.tgz arc_dir --exclude=dir/ignore_this_dir

使用 tar 從備份中排除文件/目錄的可能選項:

使用多種模式排除文件

tar -czf backup.tar.gz --exclude=PATTERN1 --exclude=PATTERN2 ... /path/to/backup

使用填充了模式列表的排除文件排除文件

tar -czf backup.tar.gz -X /path/to/exclude.txt /path/to/backup

通過將標記文件放置在應跳過的任何目錄中來排除使用標記的文件

tar -czf backup.tar.gz --exclude-tag-all=exclude.tag /path/to/backup

有很多答案的老問題,但我發現沒有一個對我來說足夠清楚,所以我想添加我的嘗試。

如果你有以下結構

/home/ftp/mysite/

帶有以下文件/文件夾

/home/ftp/mysite/file1
/home/ftp/mysite/file2
/home/ftp/mysite/file3
/home/ftp/mysite/folder1
/home/ftp/mysite/folder2
/home/ftp/mysite/folder3

因此,您想制作一個包含 /home/ftp/mysite 中所有內容的 tar 文件(將站點移動到新服務器),但file3只是垃圾,並且folder3所有內容也都不需要,因此我們將跳過這些二。

我們使用格式

tar -czvf <name of tar file> <what to tar> <any excludes>

其中 c = create、z = zip 和 v = verbose(您可以看到輸入的文件,這有助於確保沒有添加您排除的文件)。 和 f= 文件。

所以,我的命令看起來像這樣

cd /home/ftp/
tar -czvf mysite.tar.gz mysite --exclude='file3' --exclude='folder3'

請注意,排除的文件/文件夾相對於您的 tar 的根目錄(我在這里嘗試了相對於 / 的完整路徑,但我無法使其工作)。

希望這會幫助某人(還有我下次谷歌搜索時)

您可以使用標准的“螞蟻符號”來排除相對目錄。
這對我有用,不包括任何 .git 或 node_module 目錄:

tar -cvf myFile.tar --exclude=**/.git/* --exclude=**/node_modules/*  -T /data/txt/myInputFile.txt 2> /data/txt/myTarLogFile.txt

myInputFile.txt 包含:

/dev2/java
/dev2/javascript

這個排除模式處理像 png 或 mp3 這樣的文件名后綴以及像 .git 和 node_modules 這樣的目錄名

tar --exclude={*.png,*.mp3,*.wav,.git,node_modules} -Jcf ${target_tarball}  ${source_dirname}

我已經經歷過,至少在我使用的Cygwin版本的 tar 中 ("CYGWIN_NT-5.1 1.7.17(0.262/5/3) 2012-10-19 14:39 i686 Cygwin" on Windows XP Home Edition SP3 機器),選項的順序很重要。

雖然這個結構對我有用:

tar cfvz target.tgz --exclude='<dir1>' --exclude='<dir2>' target_dir

那個沒有用

tar cfvz --exclude='<dir1>' --exclude='<dir2>' target.tgz target_dir

這一點,而tar --help顯示以下內容:

tar [OPTION...] [FILE]

所以,第二個命令也應該有效,但顯然情況並非如此......

最好的 rgds,

我在其他地方發現了這個,所以我不會相信,但對於我的 mac 特定問題,它比上面的任何解決方案都更好(即使這是關閉的):

tar zc --exclude __MACOSX --exclude .DS_Store -f <archive> <source(s)>

對於 Mac OSX 我必須做

tar -zcv --exclude='folder' -f theOutputTarFile.tar folderToTar

注意--exclude=后面的-f

對於那些遇到問題的人來說,某些版本的 tar 只能在排除值中沒有“./”的情況下才能正常工作。

Tar --version

焦油(GNU 焦油)1.27.1

有效的命令語法:

tar -czvf ../allfiles-butsome.tar.gz * --exclude=acme/foo

這些將不起作用:

$ tar -czvf ../allfiles-butsome.tar.gz * --exclude=./acme/foo
$ tar -czvf ../allfiles-butsome.tar.gz * --exclude='./acme/foo'
$ tar --exclude=./acme/foo -czvf ../allfiles-butsome.tar.gz *
$ tar --exclude='./acme/foo' -czvf ../allfiles-butsome.tar.gz *
$ tar -czvf ../allfiles-butsome.tar.gz * --exclude=/full/path/acme/foo
$ tar -czvf ../allfiles-butsome.tar.gz * --exclude='/full/path/acme/foo'
$ tar --exclude=/full/path/acme/foo -czvf ../allfiles-butsome.tar.gz *
$ tar --exclude='/full/path/acme/foo' -czvf ../allfiles-butsome.tar.gz *

在閱讀了所有這些不同版本的好答案並為我自己解決了問題之后,我認為有一些非常重要的小細節,對於 GNU/Linux 的一般使用來說是很少見的,沒有足夠的壓力,值得更多的評論。

因此,我不會嘗試針對每種情況都回答這個問題,而是嘗試注冊在出現問題時應查看的位置

請務必注意:

  1. 選項的順序很重要:在文件選項和要備份的目錄之前和之后放置 --exclude 是不一樣的。 這至少對我來說是出乎意料的,因為根據我的經驗,在 GNU/Linux 命令中,選項的順序通常無關緊要。
  2. 不同的 tar 版本期望此選項的順序不同:例如, @Andrew 的回答表明,在 GNU tar v 1.26 和 1.28 中,排除項排在最后,而在我的情況下,對於 GNU tar 1.29,則相反。
  3. 尾隨斜線很重要:至少在 GNU tar 1.29 中,它不應該是任何.

就我而言,對於 Debian 伸展上的 GNU tar 1.29,有效的命令是

tar --exclude="/home/user/.config/chromium" --exclude="/home/user/.cache" -cf file.tar  /dir1/ /home/ /dir3/

引號無關緊要,無論有沒有它們都可以使用。

我希望這對某人有用。

如果您試圖排除版本控制系統 (VCS) 文件,tar 已經支持兩個有趣的選項! :)

  1. 選項:-- exclude-vcs

此選項不包括以下版本控制系統使用的文件和目錄: CVSRCSSCCSSVNArchBazaarMercurialDarcs

從 1.32 版開始,以下文件被排除在外:

  • CVS/及其下的所有內容
  • RCS/及其下的所有內容
  • SCCS/及其下的所有內容
  • .git/及其下的所有內容
  • .gitignore
  • .gitmodules
  • .gitattributes
  • .cvsignore
  • .svn/及其下的所有內容
  • .arch-ids/及其下的所有內容
  • {arch}/ ,以及它下面的所有內容
  • =RELEASE-ID
  • =meta-update
  • =update
  • .bzr
  • .bzrignore
  • .bzrtags
  • .hg
  • .hgignore
  • .hgrags
  • _darcs

    1. 選項:-- exclude-vcs-ignores

在歸檔某個版本控制系統 (VCS) 下的目錄時,從該 VCS 的忽略文件(例如.cvsignore.gitignore等)中讀取排除模式通常很方便。此選項提供了這種可能性。

在歸檔目錄之前,請查看它是否包含以下任何文件: cvsignore.gitignore.bzrignore.hgignore 如果是這樣,請從這些文件中讀取忽略模式。

模式的處理方式與相應的 VCS 處理方式相同,即:

.cvsignore

包含僅適用於此文件所在目錄的 shell 樣式的通配模式。 文件中不允許有任何評論。 空行被忽略。

.gitignore

包含外殼樣式的通配模式。 適用於.gitfile所在目錄及其所有子目錄。

任何以#開頭的行都是注釋。 反斜杠轉義注釋字符。

.bzrignore

包含 shell globbing-patterns 和正則表達式(如果前綴為RE: (16)。模式影響目錄及其所有子目錄。

任何以#開頭的行都是注釋。

.hgignore

包含 posix 正則表達式 (17)。 syntax: glob切換到 shell globbing 模式。 syntax: regexp切換回來。 注釋以#開頭。 模式影響目錄及其所有子目錄。

  1. 例子

tar -czv --exclude-vcs --exclude-vcs-ignores -f path/to/my-tar-file.tar.gz path/to/my/project/

我同意 --exclude 標志是正確的方法。

$ tar --exclude='./folder_or_file' --exclude='file_pattern' --exclude='fileA'

對我沒有立即發現的副作用的警告:在此示例中排除 'fileA' 將重復搜索 'fileA'

示例:具有單個子目錄的目錄,其中包含一個同名文件 (data.txt)

data.txt
config.txt
--+dirA
  |  data.txt
  |  config.docx
  • 如果使用--exclude='data.txt'存檔將不包含EITHER的data.txt文件。 如果歸檔第三方庫(例如 node_modules 目錄),這可能會導致意外結果。

  • 為避免此問題,請確保提供完整路徑,例如--exclude='./dirA/data.txt'

閱讀完這篇文章后,我對 RHEL 5 進行了一些測試,以下是我對 abc 目錄進行 tar 壓縮的結果:

這將排除目錄錯誤和日志以及目錄下的所有文件:

tar cvpzf abc.tgz abc/ --exclude='abc/error' --exclude='abc/logs'

在排除目錄后添加通配符將排除文件但保留目錄:

tar cvpzf abc.tgz abc/ --exclude='abc/error/*' --exclude='abc/logs/*'

為了避免由於使用find ... | xargs ...可能出現的'xargs: Argument list too long'錯誤find ... | xargs ... find ... | xargs ...文件的處理時,幾萬,你可以管的輸出find直接tar使用find ... -print0 | tar --null ... find ... -print0 | tar --null ... .

# archive a given directory, but exclude various files & directories 
# specified by their full file paths
find "$(pwd -P)" -type d \( -path '/path/to/dir1' -or -path '/path/to/dir2' \) -prune \
   -or -not \( -path '/path/to/file1' -or -path '/path/to/file2' \) -print0 | 
   gnutar --null --no-recursion -czf archive.tar.gz --files-from -
   #bsdtar --null -n -czf archive.tar.gz -T -

您還可以根據需要使用“--exclude-tag”選項之一:

  • --exclude-tag=文件
  • --exclude-tag-all=文件
  • --exclude-tag-under=文件

將排除托管指定 FILE 的文件夾。

將 find 命令與 tar append (-r) 選項結合使用。 通過這種方式,您可以一步將文件添加到現有的 tar,而不是兩遍的解決方案(創建文件列表,創建 tar)。

find /dir/dir -prune ... -o etc etc.... -exec tar rvf ~/tarfile.tar {} \;

gnu tar v 1.26 --exclude 需要在歸檔文件和備份目錄參數之后,應該沒有前導或尾部斜杠,並且不喜歡引號(單引號或雙引號)。 所以相對於要備份的 PARENT 目錄,它是:

tar cvfz /path_to/mytar.tgz ./dir_to_backup --exclude=some_path/to_exclude

您可以使用 cpio(1) 創建 tar 文件。 cpio 將文件歸檔到標准輸入中,因此如果您已經找到了要用於選擇歸檔文件的 find 命令,請將其通過管道傳輸到 cpio 以創建 tar 文件:

find ... | cpio -o -H ustar | gzip -c > archive.tar.gz
tar -cvzf destination_folder source_folder -X /home/folder/excludes.txt

-X 表示包含必須從備份中排除的文件名列表的文件。 例如,您可以在此文件中指定 *~ 以在備份中不包含任何以 ~ 結尾的文件名。

排除絕對路徑的目錄似乎是不可能的。 一旦任何路徑是絕對路徑(源或/和排除),排除命令將不起作用。 這是我嘗試所有可能組合后的經驗。

一探究竟

tar cvpzf zip_folder.tgz . --exclude=./public --exclude=./tmp --exclude=./log --exclude=fileName

成功案例: 1)如果給全路徑備份,在排除也應該使用全路徑。

tar -zcvf /opt/ABC/BKP_27032020/backup_27032020.tar.gz --exclude='/opt/ABC/csv/ ' --exclude='/opt/ABC/log/ ' /opt/ABC

2) 如果給當前路徑做備份,在排除中也應該只使用當前路徑。

tar -zcvf backup_27032020.tar.gz --exclude='ABC/csv/ ' --exclude='ABC/log/ ' ABC

失敗案例:

  1. 如果讓當前路徑目錄進行備份並忽略完整路徑,則將無法正常工作

    tar -zcvf /opt/ABC/BKP_27032020/backup_27032020.tar.gz --exclude='/opt/ABC/csv/ ' --exclude='/opt/ABC/log/ ' ABC

注意:在備份目錄之前/之后提到排除是可以的。

我想展示另一個選項,我用來獲得與提供之前的答案相同的結果,我有一個類似的案例,我想使用du命令將 android studio 項目全部備份在一個 tar 文件中以上傳到 media fire為了找到大文件,我發現我不需要一些目錄,例如:build, linux e .dart_tools 使用 Charles_ma 的第一個答案我稍微修改了它,以便能夠從我的父目錄運行命令安卓目錄。

tar --exclude='*/build' --exclude='*/linux' --exclude='*/.dart_tool' -zcvf androidProjects.tar Android/

它就像一個魅力。

附言。 對不起,如果不允許這種答案,如果是這種情況我會刪除。

可能是多余的答案,但因為我發現它很有用,所以這里是:

雖然是 FreeBSD 根目錄(即使用 csh),但我想將整個根文件系統復制到 /mnt 但沒有 /usr 和(顯然)/mnt。 這是有效的(我在/):

tar --exclude ./usr --exclude ./mnt --create --file - . (cd /mnt && tar xvd -)

我的重點是有必要(通過放置./指定tar 排除目錄,其中部分目錄被復制。

我的 0.02 歐元

我沒有運氣讓 tar 排除幾級深的 5 GB 子目錄。 最后,我只是使用了 unix Zip 命令。 它對我來說容易多了。

因此,對於原始帖子中的這個特定示例
(tar --exclude='./folder' --exclude='./upload/folder2' -zcvf /backup/filename.tgz .)

相當於:

zip -r /backup/filename.zip 。 -x 上傳/文件夾/**\\* 上傳/文件夾 2/**\\*

(注意:這是我最初使用的幫助我的帖子https://superuser.com/questions/312301/unix-zip-directory-but-excluded-specific-subdirectories-and-everything-within-t

我想在本地主機上擁有新的前端版本(角度文件夾)。 另外,在我的情況下,git 文件夾很大,我想排除它。 我需要從服務器下載它,然后解壓它才能運行應用程序。

從 /var/lib/tomcat7/webapps 壓縮 angular 文件夾,將其移動到名為 angular.23.12.19.tar.gz 的 /tmp 文件夾

命令 :

tar --exclude='.git' -zcvf /tmp/angular.23.12.19.tar.gz /var/lib/tomcat7/webapps/angular/

最好的辦法是通過 xargs 將 find 與 tar 一起使用(以處理大量參數)。 例如:

find / -print0 | xargs -0 tar cjf tarfile.tar.bz2

以下 bash 腳本應該可以解決問題。 它使用了 Marcus Sundman 在此處給出的答案。

#!/bin/bash

echo -n "Please enter the name of the tar file you wish to create with out extension "
read nam

echo -n "Please enter the path to the directories to tar "
read pathin

echo tar -czvf $nam.tar.gz
excludes=`find $pathin -iname "*.CC" -exec echo "--exclude \'{}\'" \;|xargs`
echo $pathin

echo tar -czvf $nam.tar.gz $excludes $pathin

這將打印出您需要的命令,您只需將其復制並粘貼回即可。可能有一種更優雅的方式將其直接提供給命令行。

只需將 *.CC 更改為您想要排除的任何其他常見擴展名、文件名或正則表達式,這應該仍然有效。

編輯

只是補充一點解釋; find 生成與所選正則表達式匹配的文件列表(在本例中為 *.CC)。 該列表通過 xargs 傳遞給 echo 命令。 這會打印 --exclude 'one entry from the list'。 斜線 () 是 ' 標記的轉義字符。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM