2013-12-13 53 views
9

我有以下結構:正在同步單個文件,並保持文件夾結構的N級

/Users 
    /build 
    /.jenkins 
     /jobs 
     /Job1 
      config.xml 
      someotherfiles.blah 
     /Job2 
      config.xml 
      someotherfiles.blah 
     /JobN 
      config.xml 
      someotherfiles.blah 

我想只備份config.xml文件到另一個文件夾保存的文件夾結構相同的新文件夾,但修剪掉/User/build/.jenkins/jobs

我的新文件夾應該是這樣的:

backup/ 
    /Job1 
    config.xml 
    /Job2 
    config.xml 
    /JobN 
    config.xml 

這是可能使用rsync做什麼?

編輯:不小心包括someotherfiles.blah輸出,我其實不想這些。我想要的只是config.xml文件以及1級文件夾結構。

回答

1

在這裏你去:

find ./build/.jenkins/jobs/* | 
grep -i 'someotherfiles.blah' | 
cut -d/-f 5- | 
rsync -v -r --exclude-from=- ./build/.jenkins/jobs/ ./output 

步驟,這是發生了什麼事:

find ./build/.jenkins/jobs/* 

這提供了在指定的路徑的目錄/文件列表。它的輸出是

./build/.jenkins/jobs/Job1 
./build/.jenkins/jobs/Job1/config.xml 
./build/.jenkins/jobs/Job1/someotherfiles.blah 
./build/.jenkins/jobs/Job2 
./build/.jenkins/jobs/Job2/config.xml 
./build/.jenkins/jobs/Job2/someotherfiles.blah 
./build/.jenkins/jobs/Job3 
./build/.jenkins/jobs/Job3/config.xml 
./build/.jenkins/jobs/Job3/someotherfiles.blah 

然後,我們將其管理到grep命令,在那裏我們可以放入任何我們想要過濾的模式。在我的例子,我grepping排除someotherfiles.blah

find ./build/.jenkins/jobs/* | 
grep -i 'someotherfiles.blah' 

輸出

./build/.jenkins/jobs/Job1/someotherfiles.blah 
./build/.jenkins/jobs/Job2/someotherfiles.blah 
./build/.jenkins/jobs/Job3/someotherfiles.blah 

現在的rsync將採取從標準的模式列表從其同步排除。它需要具有與其src參數相關的路徑,所以我們從out列表中刪除了前幾個目錄。

find ./build/.jenkins/jobs/* | 
grep -i 'someotherfiles.blah' | 
cut -d/-f 5- 

輸出:

Job1/someotherfiles.blah 
Job2/someotherfiles.blah 
Job3/someotherfiles.blah 

現在,我們管這給它rsync的使用--exclude-從= - 的說法。這將告訴它從stdin中排除文件。

find ./build/.jenkins/jobs/* | 
grep -i 'someotherfiles.blah' | 
cut -d/-f 5- | 
rsync -v -r --exclude-from=- ./build/.jenkins/jobs/ ./output 

building file list ... done 
Job1/ 
Job1/config.xml 
Job2/ 
Job2/config.xml 
Job3/ 
Job3/config.xml 

sent 318 bytes received 104 bytes 844.00 bytes/sec 
total size is 15 speedup is 0.04 

該解決方案是使用grep來查找文件的列表從rsync將排除輸出。你可能希望grep表達式只包含某些文件。您也可以使用--include-from = - 參數來執行此操作。還有一個變化。下面是這個完整的代碼,其中僅複製的config.xml文件

find ./build/.jenkins/jobs/ | 
grep -i 'config.xml' | 
cut -d/-f 5- | 
awk -F/ '{print; while(/\//) {sub("/[^/]*", ""); print}}'| 
rsync -v -r --include-from=- --exclude='*' ./build/.jenkins/jobs/ ./output 

當你添加的東西到--exclude列表,rsync的將不會搜索列表中的所有子目錄。顯然,我們不需要這樣,因爲我們在Job1,2,3文件夾中有config.xml文件!所以我們使用awk將我們想要搜索config.xml文件的父目錄添加到我們的輸出中。

之後,我們讓rsync --include-從我們的標準輸入,並排除其他一切(「*」)

以上使用相對路徑的路徑,如果你使用絕對路徑,根據需要修改路徑和確保cut命令中的-f參數選擇正確的標記號碼以切入。

反正,將這些命令保存在一個.sh文件中,你應該有一個方便的小工具來使用。

+0

我更新了我的問題,使其更加清晰。我認爲你的解決方案只能工作,因爲測試文件夾與你當前目錄的相對性。如果你包含完整路徑,比如'/ User//test/*',我確定它會複製'output'裏面的整個文件夾結構。 – ThaDon

+0

好吧,我不認爲rsync可以做到這一切,您需要將其他一些unix命令一起傳輸。我將重新回答 – 75inchpianist

+0

併爲了記錄,不,我嘗試了完全絕對路徑,它仍然有效。請參閱上面的編輯。 – 75inchpianist

3

這應該工作:

rsync -r --include=Job* --include=config.xml --exclude=* /full/path/to/Users/build/.jenkins/ backup 

的完整路徑,除非你通過-R選項,rsync的不被複制到備份目錄。如果您包括Job*和​​3210,然後排除*(順序很重要,因爲與包含或排除規則的第一個匹配決定了要複製的內容),您最終會得到所需的結構。如果具有明確Job*模式過於嚴格,手冊上說,你應該能夠使用*/模式:

一種解決方案是通過使用單一規則的層次,要求所有的目錄被包含 : 「+ * /」(放在「 - *」規則之前的某處)

查看手冊頁的整個INCLUDE/EXCLUDE PATTERN RULES部分以獲取更多詳細信息。

+1

在過濾規則語法中,這是:'+ config.xml''+ * /'' - *'(使用'--filter'應用) –

1

您可以使用--relative選項指定文件夾級別。

從手冊:

它也可以限制發送爲每個指定的路徑隱含目錄的路徑信息的量。隨着在發送端(2.6.7帶開始)現代rsync的,你可以插入一個點和斜線到源路徑,像這樣:

rsync -avR /foo/./bar/baz.c remote:/tmp/ 

在這個例子中,--relative選項將啓動從第二級創建文件夾。在遙控器上:

/tmp 
|_ bar 
    |_ baz.c 
+0

嘗試過,工作。這是最有效的方法。我想知道爲什麼沒有人投票。我是第一個幸運的人。很有用。謝謝! – fanchyna

相關問題