Znajdź pliki według długości nazwy pliku


10

Chcę znaleźć wszystkie pliki według długości nazw plików.

Na przykład, jeśli chcę znaleźć pliki o długości 1, takie jak a.go, b.go.

Włożyłem:

grep '.\{1\}' file

Ale to nie działa. Jakiego polecenia mogę użyć do znalezienia plików według długości nazwy pliku?


a.goto nazwa pliku o długości 4. ato nazwa pliku o długości 1. To jest Uniks, a nie DOS, gdzie nazwa i rozszerzenie były osobne, a domniemana .zawsze była częścią nazwy pliku.
Peter Cordes,

Odpowiedzi:


3

grepszuka wzorców w zawartości plików. Jeśli chcesz spojrzeć na nazwy plików, możesz po prostu użyć powłoki glob (jeśli chcesz wziąć pod uwagę tylko nazwy plików w bieżącym katalogu):

echo ?.go

(Nawiasem mówiąc, to powłoka ocenia glob, a nie echopolecenie).

Jeśli chcesz przeglądać katalogi rekurencyjnie, zaczynając od bieżącego katalogu, narzędziem do użycia jest find:

find . -name '?.go'

(Pamiętaj, że musisz zacytować wzorzec, aby powłoka nie oceniła go jako globu przed findwywołaniem).


1
Znajdziesz tu również katalogi, które również pasują do wzorca „? .Go”.
slm

@slm, katalogi są jednym z wielu rodzajów plików, OP nie określił, jakiego rodzaju plików szukał.
Stéphane Chazelas,

8

Jeśli chcesz tylko znaleźć nazwy plików, możesz użyć następującego polecenia:

find -exec basename '{}' ';' | egrep '^.{100,}$'

To się uruchomi find, ściągając nazwę pliku lub katalogu za pomocą, basenamea następnie wyszukuje nazwę pliku lub nazwę katalogu, która ma co najmniej 100 znaków. Jeśli chcesz znaleźć nazwę pliku o dokładnej długości, użyj {100}zamiast {100,}.

Jeśli chcesz znaleźć nazwy plików, w tym ścieżkę, wykonaj następujące czynności:

find | egrep '/[^/]{100,}$'

Zwróci to nazwę pliku wraz ze ścieżką względną do miejsca, w którym uruchomiono polecenie find.


3

Po pierwsze, grepprzeszukuje zawartość plików, nie szuka nazw plików. Do tego chcesz find. Nie ma opcji ustawiania długości nazwy pliku, ale możesz przeanalizować jego wynik, aby uzyskać to, czego chcesz. Oto kilka przykładów, które uruchamiam w katalogu zawierającym następujące pliki:

$ tree
.
├── a
├── ab
├── abc
├── abcd
└── dir
    ├── a
    ├── ab
    ├── abc
    └── abcd

Wyszukiwanie plików w tym katalogu zwraca:

$ find . -type f | sort
./a
./ab
./abc
./abcd
./dir/a
./dir/ab
./dir/abc
./dir/abcd

Aby znaleźć pliki o długości X, musimy usunąć ścieżkę i dopasować tylko znaki po ostatnim /:

 $ find . -type f | grep -P '/.{3}$'

sedKomenda tylko usuwa ./. -PFlaga uaktywnia Perl Compatible Regular Expressions, które są potrzebne na {n}co jest rzeczą PCRE i $oznacza „dopasować koniec napisu”.

Możesz również po prostu to zrobić:

find . -type f | grep -P '/...$'

To dobrze, jeśli małe liczby wpisujące 15 kropek w celu dopasowania nazw plików o długości 15 nie są zbyt wydajne.

Na koniec, jeśli chcesz zignorować rozszerzenie i dopasować tylko nazwę pliku, zrób to (zgodnie z sugestią @slm):

find . -type f | grep -P '/.{1}\.'

Jednak znajdzie to również pliki takie jak a.bo.go. Jest to lepsze, jeśli twoje nazwy plików mogą zawierać więcej niż jeden .:

find . -type f | grep -P '/.{1}\.[^.]+$'

UWAGA: Powyższe rozwiązanie zakłada, że ​​masz względnie rozsądne nazwy plików, które nie zawierają nowych znaków wiersza itp. Będzie również liczyć nie ignorować spacji w nazwach plików podczas obliczania długości, która może być inna niż chcesz. Jeśli któryś z tych problemów stanowi problem, daj mi znać, a zaktualizuję odpowiedź.


1

Nie określasz, ale jeśli pliki mieszczą się w strukturze katalogów, możesz użyć finddo zlokalizowania plików o długości 1 za pomocą grep:

$ find . -type f  | grep -P '/.{1}\.'

Przykład

$ find . -type f  | grep -P '/.{1}\.' | head -10
./util-linux-2.19/include/c.h
./88366/a.bash
./89186/a.bash
./89563/b.txt
./89563/a.txt
./89563/c.txt
./89563/d.txt
./91734/2.c
./91734/4.c
./91734/1.c

W MacOS X użyj egrep i usuń opcję -P
Bart Kummel

@BartKummel - faktycznie na OSX używam ggrep: heystephenwood.com/2013/09/install-gnu-grep-on-mac-osx.html . Zrozum również, że to Q nie było oznaczone jako OSX, więc użycie grepjest poprawne.
slm

1

Użyłbym czegoś takiego.

find . -type f -name "?.go"

Więc jeśli wstawisz dwa „?” to szukasz nazw plików z dwoma znakami i rozszerzeniem.


0

Jeśli chcesz użyć wyrażenia regularnego w poleceniu find, powinieneś użyć ""takich jak:

find /var/log -iname "*.err" 

w takim przypadku użyj:

find yourpath -type f -a -name "?.go"

Powinieneś zastąpić swoją prawdziwą ścieżkę swoją ścieżką, -aoznacza And -type fto, że szukasz tylko zwykłych plików.

? w zapytaniu oznacza jeden charachter, taki jak DOS, jeśli pamiętasz.


-1

ls ?.* powinno dać pożądane rezultaty.


witamy na Unix.SE. Niestety, nie jest przydatne dodawanie odpowiedzi na stare pytania, które już zawierają wiele dobrych odpowiedzi. (Chyba że istnieje nowy lepszy sposób rozwiązania starego problemu lub masz lepsze rozwiązanie niż którakolwiek ze starych odpowiedzi). Jeśli chcesz odpowiedzieć na niektóre pytania, spójrz na nowe pytania na pierwszej stronie.
Peter Cordes,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.