2014-06-16 38 views
7

OS Linux Mint的找到並複製所有圖像使用終端Linux Mint的目錄,試圖瞭解語法

就像標題所說終於我想找到並複製所有圖像的目錄。

我發現:

找到承滴盤JPG(或JPG)目錄中的文件,並將它們複製到文件夾/ home /約阿希姆/ NEU2:

find . -iname \*.jpg -print0 | xargs -I{} -0 cp -v {} /home/joachim/neu2 

發現所有圖像文件在目錄中:

find . -name '*' -exec file {} \; | grep -o -P '^.+: \w+ image' 

我的問題首先是,我不太瞭解語法。有人可以解釋代碼嗎?

其次有人可以連接兩個代碼生成我想要做什麼代碼;)

問候,並在此先感謝!

再次對代碼的解釋會非常有幫助。

回答

15

首先,明白管道「|」 links命令將第一個的輸出傳遞給第二個作爲參數。您的兩個shell代碼都將find命令的輸出輸出到其他命令(grep和xargs)中。讓我們來看看這些命令此起彼伏:

首先命令:find

發現是一個程序(即從發現的手冊頁說明)以「在目錄層次結構中搜索文件」。語法是(在這種情況下)

find <search directory> <search pattern> <action> 

在這兩種情況下,搜索目錄都是。 (這是當前目錄)。請注意,它不僅搜索當前目錄,也搜索其所有子目錄(目錄層次結構)。

搜索模式接受選項-name(意思是它搜索名稱與作爲參數給出的模式相匹配的文件)或-iname(與名稱相同但區分大小寫)等等。

動作模式可能是-print0(打印確切的文件名,包括它在給定搜索目錄中的位置,即文件的相對或絕對路徑)或-exec(在文件上執行給定的命令,該命令將以「;」結尾,並且每個「{}」實例都將由文件名替換)。

也就是說,第一個shell代碼(第一部分,左管)

find . -iname \*.jpg -print0 

搜索在當前目錄層次結束「.JPG」,並打印自己的路徑和名稱的所有文件。第二個(第一部分)

find . -name '*' -exec file {} \; 

發現在當前目錄層次結構中的所有文件,並對其執行

file <filename> 

。 File是決定和打印文件類型的另一個命令(查看手冊頁中的詳細信息,man文件)。

第二命令:xargs的

xargs的是一個命令,「構建並從標準輸入exectues命令行」(人xargs的),即從被管道輸送到xargs的查找輸出。它建立並執行該命令是在這種情況下

cp -v {} /home/joachim/neu2" 

選項-I {}定義了替換字符串,即{}中的指令是由它從文件中獲取輸入來代替每個實例(即是,文件名)。選項-0定義輸入項不會被空格或換行符終止(分隔),而只會被空字符終止。這似乎是必要的,當使用和標準的方式來處理查找輸出作爲xargs輸入。

然後,構建並執行的命令當然是帶有選項-v(詳細)的複製命令,它將從查找到的每個文件名複製到目錄。

第三命令:grep的

grep的濾波器其輸入只給那些符合特定輸出模式的行或字符串。選項-o告訴grep只打印匹配的字符串,而不是整行(參見man grep),-P告訴它將下面的模式解釋爲perl正則表達式模式。在perl正則表達式中,^是行的開始,。+是任意的字符串,這個任意的後面應該跟一個冒號,一個空格,一些字母數字字符(在perl regex中表示爲\ w +)一個空格和字符串「圖片」。本質上這個grep命令過濾文件輸出只輸出圖像文件的文件名。 (閱讀有關Perl的正則表達式的比如這裏:http://www.comp.leeds.ac.uk/Perl/matching.html

你其實想

你想要做的是:(1)取第二個shell命令的輸出(其中列出的圖像文件現在什麼命令),(2)將它引入適當的形式,(3)將它從第一個shell命令行(然後構建並執行所需的複製命令)導入到xargs命令中。所以這次我們有三個(實際上是四個)階段shell命令和兩個管道。不是問題。我們已經有了階段(1)和(3)(儘管在階段(3)中我們需要省略-0選項,因爲輸入不再被查找輸出;我們需要它將新換行符當作項目分隔符)。

階段(2)仍然缺失。我建議爲此使用cut命令。剪切更改字符串py分裂成不同的領域(由原始字符串中的分隔符分隔),然後可以重新排列。我將選擇「:」作爲分隔符(這將在grep輸出中結束文件名,選項-d':'),並告訴它給我們第一個字段(選項-f1,essentialls:僅打印文件名,而不是「:」之後的部分),即階段(2),然後將

cut -d':' -f1 

然後你想整個命令將是:

find . -name '*' -exec file {} \; | grep -o -P '^.+: \w+ image' | cut -d':' -f1 | xargs -I{} cp -v {} /home/joachim/neu2 

注意,你可以找到所有例如這裏的手冊頁:http://www.linuxmanpages.com

+0

非常感謝你!你的回答包含了非常多的信息,真正幫助我更好地理解整個事情。 – newandlost

+0

爲了理解這些命令,有多少人知道它是多麼的瘋狂。 – newandlost

+0

當你說 「...或-exec(在文件上執行給定的命令時,命令將以」;「結尾......」 你確實是指\;或者爲什麼是有一個\? – newandlost

0

我想出了一個命令只使用awk來完成這項工作:

find . -name '*' -exec file {} \; | 
awk '{ 
    if ($3=="image"){ 
     print substr($1, 0, length($1)-1); 
     system("cp " substr($1, 0, length($1)-1) " /home/joachim/neu2") 
    } 
}' 

substr($ 1,0,len gth($ 1)-1),因爲在第一列文件中返回名稱;

0

以上答案真的很好。但如果它是一個巨大的目錄,可能需要更長時間。 這裏是它的一個較短的版本,如果你已經知道你的文件擴展名

find . -name \*.jpg | cut -d':' -f1 | xargs -I{} cp --parents -v {} ~/testimage/ 
相關問題