2009-04-26 13 views
11

Z dokumentacji:Zmieszany z -Include parametr cmdlet Get-ChildItem

-include

Pobiera tylko określone elementy. Wartość tego parametru kwalifikuje parametr Ścieżka. Wprowadź element lub deseń ścieżki, na przykład "* .txt". Symbole wieloznaczne są dozwolone.

włączeń parametr jest skuteczne tylko wtedy, gdy komenda zawiera parametr recurse lub ścieżka prowadzi do zawartości katalogu , takich jak C: \ Windows *, gdzie symbol wieloznaczny określa zawartość C: \ katalog Windows.

Moje pierwsze zrozumienie było:

c:\test\a.txt 
c:\test\b.txt 

Tak, aby uzyskać 'a.txt' i 'b.txt' mogę napisać:

gci -Path "c:\test\*" -Include "*.txt" 

I to działa. Ale teraz rozważyć taką hierarchię:

c:\test\a.txt 
c:\test\b.txt 
c:\test\c.txt\c.txt 

Te same powraca polecenie: a.txt, b.txt, c.txt

Rzeczywista logika wydaje się być:

-include używane aby dopasować wszystkie elementy określone przez -Path. Jeśli dopasowany element jest plikiem - zwróć go. Jeśli pasuje element jest folderem, zajrzyj do środka i zwróć pasujące elementy potomne pierwszego poziomu.

Również dokumentacja powiedzieć:

włączeń parametr jest skuteczne tylko wtedy, gdy komenda zawiera parametr recurse lub ścieżka prowadzi do zawartości katalogu ...

To również jest złe. Na przykład.

gci -Path "c:\test" -Include "*.txt" 

Nic nie zwraca, natomiast bez opcji -Interclude otrzymuję zawartość folderu. Tak-Include jest zdecydowanie "skuteczny". Co tak naprawdę się tutaj dzieje? -Path określa "c: \ test", a -Include próbuje dopasować tę ścieżkę. Ponieważ "* .txt" nie pasuje do "testu", więc nic nie wróciło. Ale spójrz na to:

gci -Path "c:\test" -Include "*t" 

Zwraca a.txt, b.txt i c.txt jako "* t" dopasowane "test" i dopasowane wszystkie elementy podrzędne.

W końcu, nawet wiedząc, jak działa teraz Włącz, nie rozumiem, kiedy go używać. Dlaczego powinienem szukać wewnątrz podfolderów? Dlaczego miałoby to być tak skomplikowane?

Odpowiedz

14

Dezorientujesz korzystanie z opcji -include.Flaga -include jest stosowana do ścieżki, a nie do zawartości ścieżki. Bez użycia flagi rekursywnej jedyną dostępną ścieżką jest określona ścieżka. Właśnie dlatego ostatni przykład, który dałeś pracy, ścieżka c:\test ma t na ścieżce i dlatego pasuje do "*t".

Można to sprawdzić próbując następujące

gci -path "c:\test" -in *e* 

ten nadal będzie produkować wszystkie dzieci w katalogu jeszcze pasuje żaden z ich nazwami.

Powodem, dla którego opcja -include jest bardziej efektywna w przypadku parametru recurse, jest to, że kończy się stosowanie symbolu wieloznacznego na każdą ścieżkę w hierarchii.

+0

Używam programu PowerShell-v2.0-CTP3, a Twój przykład generuje pusty zestaw. – alex2k8

+0

@ alex2k8, Nie jestem pewien, co powiedzieć tutaj. Próbowałem tego przykładu w wersji 1.0 i późniejszej wersji 2.0, oba dają takie same wyniki. – JaredPar

+0

@Jared, to dziwne. Proszę, możesz spróbować gci -path c: \ * -in *. Widzę dzieci z c: \ i wszystkich podfolderów o jeden poziom niżej. Oto podobny opis http://www.eggheadcafe.com/software/aspnet/32624832/getchilditem-include-qu.aspx – alex2k8

4

Tacking na JaredPar's answer, w celu dopasowania wzorców do Get-ChildItem, można użyć standardowych symboli wieloznacznych powłoki.

Na przykład: "?"

get-childitem "c:\test\t?st.txt" 

gdzie jest symbolem wieloznacznym pasującym do dowolnego znaku lub odpowiadającym dowolnej nazwie pliku kończącej się na ".txt".

To powinno dać ci "prostsze" zachowanie, którego szukałeś.

+0

Czy to nie problem, że można uzyskać tylko jedno rozszerzenie? -Include to ciąg [] pozwalający na dopasowanie wielu odmian. Dzięki, Ben –

9

Spróbuj parametr -filter (ma wsparcie tylko jedno przedłużenie):

dir -filter * .txt

+5

Filtr jest nieco inny, ponieważ jest to implementacja specyficzna dla dostawcy. Zwykle jest bardziej wydajne, ponieważ występuje przed zwróceniem danych. Ale ma inną implementację dla każdego dostawcy napędu w PowerShell. W związku z tym mogą istnieć subtelne różnice w algorytmie dopasowywania. – JaredPar

+0

Zgadzam się, chociaż w tym przypadku mówimy o dostawcy systemu plików. Wezwanie do komentarza. –

2

właśnie zadał podobne pytanie i dostał trzy krótkie odpowiedzi dotyczące Get-Help dla Get- ChildItem.

Odpowiedź jest w pełnym opisem polecenia (get-help Get-ChildItem -full):

The Include parameter is effective only when the command includes the 

parametr Rekurencyjnie lub ścieżka prowadzi do zawartości katalogu, na przykład C: \ Windows *, gdzie znak wieloznaczny określa zawartość katalogu 01:w katalogu C: \ Windows.

Tak więc następujące czynności będą działały bez powtarzania się przez .

PS C: \ foo> Get-ChildItem -path "c: \ foo *" -include * .txt

Od przepełnienie stosu pytanie PowerShell Scripting - Get-ChildItem.

Mam nadzieję, że to pomaga :-)

+0

Ben, właściwie moje pytanie było trochę inne. Zwróć uwagę, że twój przykład zwróci pliki .txt z folderu foo, ale może także nieoczekiwanie zwrócić pliki, a nawet foldery z np. Katalogu "c: \ foo \ dir.txt". Wypróbuj taką hierarchię: c: \ foo \ dir.txt \ plik.txt i c: \ foo \ dir.txt \ dir2.txt \ plik2.txt. Otrzymasz: file.txt i dir2.txt! – alex2k8

0

Łącznie \* na końcu ścieżki powinno obejść problem

PS C:\logfiles> Get-ChildItem .\* -include *.log 

To powinno powrócić.pliki dziennika z bieżącego katalogu roboczego (C:\logfiles)

Powyższy przykład Alexa wskazuje, że katalog o nazwie foo.log również zostanie zwrócony. Kiedy go wypróbowałem, nie było, ale było to 6 lat później i mogło to być z aktualizacji PS.

Można jednak użyć elementu potomnego Mode, aby wykluczyć katalogi, które moim zdaniem.

PS C:\logfiles> Get-Childitem .\* -include *.log | where-object {$_.mode -notmatch "d"} 

Powinno to wykluczyć cokolwiek z ustawionym trybem "katalogu".

+0

Włączenie \ * na końcu ścieżki nie zawsze działa. Nie wiem, w jaki sposób określić wartość -Include, aby dopasować pliki, które nie mają rozszerzenia nazwy pliku. Określanie * jako wzorca -Include dopasowuje takie pliki, ale powoduje, że Get-ChildItem działa rekursywnie. Jeśli -Include zachował się tak samo jak Exclude, byłoby to łatwe. – MikeOnline