2016-11-29 99 views
0

我試圖運行一個搜索與git讓我在兩個文件夾之一的所有階段文件:本地或組件。我只想獲取JS文件。該命令在控制檯中運行。正則表達式開始和結束與

我到目前爲止有:

STAGED_FILES=($(git diff --cached --name-only --diff-filter=ACM | grep "^(local|components).*?.js")) 

這讓我所有的演出文件:

git diff --cached --name-only --diff-filter=ACM 

這讓我所有的文件路徑,開始與當地或組件

grep "^(local|components)" 

這讓我所有的js文件

grep ".js" 

這將返回我沒有因爲某些原因:

($(git diff --cached --name-only --diff-filter=ACM | grep "^(local|components).*?.js")) 

是什麼,我可以與搜索將讓我在這兩個文件夾的所有js文件的正則表達式?

回答

4

它沒有工作,因爲grep不支持?懶惰匹配。對於擴展正則表達式,您可以使用-E

例如,考慮這些

$ echo "asfasdfzasdfasdfz" | grep -E "a.*?z" 
asfasdfzasdfasdfz 
$ echo "asfasdfzasdfasdfz" | grep "a.*?z" 
$ echo "asfasdfzasdfasdf?z" | grep "a.*?z" 
asfasdfzasdfasdf?z 

正如你可以看到不-E它嘗試也匹配?字符串中。

+0

我不知道,謝謝! – SoluableNonagon

+0

@SoluableNonagon不客氣:) – nu11p01n73R

2

除了基於正則表達式的回答,您可以直接在Git中,其中有一個「pathspec」包括shell風格的通配的概念做到這一點:

git diff --cached --name-only \ 
    --diff-filter=ACM -- 'local/**/*.js' 'components/**/*.js' 

(線破碎顯示格式;請注意, **支持Git 1.8.2版中的新功能)。

這就是說,正則表達式比殼水珠「更強大」,所以你可能要保持nu11p01n73R's answer記在心裏。但是請注意,非貪婪匹配(*?)比賽爲越好,而不是儘可能:(反正在擴展解釋)

pattern  input  result (matched part in parentheses) 

abc.*e  0abcdefeged  0(abcdefege)d 
abc.*?e 0abcdefeged  0(abcde)feged 
abc.*d  0abcdefeged  0(abcdefeged) 
abc.*?d 0abcdefeged  0(abcd)efeged 

你的表達,^(local|components).*?.js,說:比賽行的開始;然後匹配localcomponents作爲文字文本;然後匹配儘可能少的字符,也許沒有;然後匹配任何字符;然後匹配文字j;然後匹配字面s。因此它匹配local-jaguar-xjs-vehicles,因爲它以local開頭,包含一些文本,在js之前有更多的字符,並繼續。僅

殼glob模式local/**/*.js匹配的目錄local,隨後通過任何數可能零的子目錄部件,隨後,其名稱與.js結尾的文件,與該點的字面匹配。所以這相當於模式^local/(.*/|)[^/]*\.js$:文本文本local匹配在行首,後跟一個斜線;其次是:任何數量的以斜線結尾的字符(儘可能多地),或者根本沒有;後跟除斜槓之外的任何字符(包括無),然後是文字.js,後面是行尾。

注意,因爲這種表達在兩端錨(必須在開始行末匹配),並且只有一個Kleene star在中間,也沒關係,我們是否使用貪婪或非貪婪的比賽:左邊的比賽在左邊,右邊的比賽在右邊比賽,一場貪婪的比賽儘可能多地佔據了中間位置 - 也就是所有比賽 - 而一場非貪婪的比賽作爲小中的,因爲它可以...這是仍然「所有」。

(這當然假設每行只有一個文件名被打印出來,幸運的是git diff --name-only就是這樣做的,而且所有shell都不支持shell的**「任意數量的目錄」也不是所有的非shell文件名globbing,但它用於Git的pathspecs(搜索「pathspec」)。)

+0

這實際上有很大的幫助。謝謝。 – SoluableNonagon

相關問題