Jak mogę wygenerować listę plików z bezwzględną ścieżką w systemie Linux?


304

Piszę skrypt powłoki, który pobiera ścieżki plików jako dane wejściowe.

Z tego powodu muszę wygenerować rekursywne listy plików z pełnymi ścieżkami. Na przykład plik barma ścieżkę:

/home/ken/foo/bar

ale, o ile widzę, jak lsi findtylko dać względne ofert ścieżki:

./foo/bar   (from the folder ken)

Wydaje się to oczywistym wymogiem, ale nic nie widzę na stronach podręcznika findlub ls.

Jak mogę wygenerować listę plików w powłoce wraz z ich bezwzględnymi ścieżkami?


zastosowanie:find /home/ken/foo/bar -exec ls -ld $PWD/{} \;
Uczeń

Odpowiedzi:


305

Jeśli podasz findbezwzględną ścieżkę na początek, wydrukuje ścieżki bezwzględne. Na przykład, aby znaleźć wszystkie pliki .htaccess w bieżącym katalogu:

find "$(pwd)" -name .htaccess

lub jeśli twoja powłoka rozwija $PWDsię do bieżącego katalogu:

find "$PWD" -name .htaccess

find po prostu wstawia ścieżkę, którą podano, do ścieżki względnej do pliku z tej ścieżki.

Greg Hewgill zasugerował także użycie, pwd -Pjeśli chcesz rozpoznać dowiązania symboliczne w bieżącym katalogu.


9
Zauważ, że jeśli chcesz także rozstrzygać dowiązania symboliczne, użyj pwd -P.
Greg Hewgill

5
Jest to pomocne, ale myślę, że odpowiedź user431529 poniżej jest bardziej poprawna: ls -d -1 $PWD/**/*ale chyba find $PWDdziała również (przetestowana w bash)
Brian

9
@Brian Dlaczego? find $PWDjest proste. lsZaklęcie jest złożona i nieporęczny (chyba, że go alias). findnie zależy od rozszerzeń glob powłoki, więc będzie działać w dowolnej powłoce. findjest również o wiele bardziej elastyczny, mogę uzyskać rekursywną listę wszystkich plików, a może wszystkich katalogów, a może chcę listę wszystkich plików xml lub wszystkich plików zmienionych w ostatnim tygodniu. Wszystko to jest możliwe find, ale niełatwe ls.
Matthew Scharley,

12
Musiałem użyć find "`pwd`" -name .htaccessze względu na spacje w nazwach katalogów
Paulo Casaretto

Nie rozumiem, to polecenie nie daje mi bezwzględnej ścieżki do pliku I, podczas gdy inne odpowiedzi na liście wykonują zadanie.
Bjørn Otto Vasbotten

202
readlink -f filename 

daje pełną ścieżkę absolutną. ale jeśli plik jest dowiązaniem symbolicznym, otrzymasz ostateczną rozstrzygniętą nazwę.


8
Miły. Nie działa w wariancie BSD readlink (tj. Mac). Używam gnucoreutils na Mac. Odtąd można użyć łącza dowiązania, które działa z powyższym rozwiązaniem.
sheki,

12
Nie używaj Mac OS X.
Andrew Lazarus

1
@AndrewLazarus - W przypadku systemu Mac OS X użyj realpathzamiast tego
cz

jeśli zainstalujesz narzędzia bash za pośrednictwem brew install coreutils, plik wykonywalny zostanie zainstalowany jako/usr/local/opt/coreutils/libexec/gnubin/readlink
redolent

121

Użyj tego dla katalogów ( /po **bash potrzebne jest ograniczenie, aby ograniczyć je do katalogów):

ls -d -1 "$PWD/"**/

dotyczy to plików i katalogów bezpośrednio w bieżącym katalogu, których nazwy zawierają .:

ls -d -1 "$PWD/"*.*

to na wszystko:

ls -d -1 "$PWD/"**/*

Pobrano stąd http://www.zsh.org/mla/users/2002/msg00033.html

W bash **jest rekurencyjny, jeśli włączysz shopt -s globstar.


1
ls -d -1 $ PWD / ** / * nie powtarza się. Chciałbym odebrać +1. Możesz zrobić ** dla każdej głębokości, którą musisz przejść.
user606723,

4
** operator jest rekurencyjnym operatorem globowania. Jeśli użyjesz polecenia w powłoce, która go obsługuje (np. Zsh), będzie działać poprawnie.
zebediah49

ls -d1 "$ PWD /"{*,.*}, aby również przechwycić ukryte pliki (kropkowe). Dla mnie wersja rekurencyjna w odpowiedzi nie poprzedzała bezwzględnej ścieżki do plików w podfolderach.
Zael

Myślę, że będę musiał użyć find ... I get -> bash: / bin / ls: Zbyt długa lista argumentów
TelamonAegisthus

30

Możesz użyć

find $PWD 

w bash


3
To da ścieżkę do bieżącego katalogu, a także wszystkich znajdujących się pod nim plików i katalogów. Prawdopodobnie nie tego szukają ludzie.
Bill

18
ls -d "$PWD/"*

Wygląda to tylko w bieżącym katalogu. Cytuje „$ PWD”, jeśli zawiera spacje.


To wciąż bardzo ważna odpowiedź, ale dobrze byłoby dołączyć informację, że to nie działa rekurencyjnie (i tego właśnie szukałem!)
bbbco

1
Do użytku rekurencyjnego: znajdź. -exec ls -ld $ PWD / {} \;
Uczeń

10

Komenda: ls -1 -d "$PWD/"*

To da absolutne ścieżki do pliku jak poniżej.

[root@kubenode1 ssl]# ls -1 -d "$PWD/"*
/etc/kubernetes/folder/file-test-config.txt
/etc/kubernetes/folder/file-test.txt
/etc/kubernetes/folder/file-client.txt

8

$PWDJest dobrym rozwiązaniem przez Mateusza powyżej. Jeśli chcesz znaleźć tylko pliki do wydrukowania, możesz także dodać opcję -type f, aby przeszukiwać tylko normalne pliki. Inne opcje to „d” tylko dla katalogów itp. W twoim przypadku byłoby to (jeśli chcę wyszukiwać tylko pliki z rozszerzeniem .c):

find $PWD -type f -name "*.c" 

lub jeśli chcesz wszystkie pliki:

find $PWD -type f

Uwaga: Nie można utworzyć aliasu dla powyższego polecenia, ponieważ $ PWD jest automatycznie uzupełniane do katalogu domowego, gdy alias jest ustawiany przez bash.


W rzeczywistości -d nie oznacza tylko katalogów - oznacza, że ​​traktuje katalogi jak pliki. Więc jeśli ls -d / home, wrócisz „/ home”, a nie listę tego, co jest w / home.
Travis,

@Travis: mówił o możliwości znalezienia, a nie ls. W jego przypadku „find / -type d” znajdzie tylko katalogi - jak powiedział.
oligofren

6

Jeśli podasz polecenie find bezwzględną ścieżkę, wypluje wyniki z bezwzględną ścieżką. Więc z katalogu Kena, jeśli chcesz wpisać:

find /home/ken/foo/ -name bar -print    

(zamiast ścieżki względnej find . -name bar -print)

Powinieneś wziąć:

/home/ken/foo/bar

Dlatego, jeśli chcesz ls -li zwraca on ścieżkę bezwzględną, możesz po prostu powiedzieć komendzie find, aby wykonała polecenie ls -lcokolwiek znajdzie.

find /home/ken/foo -name bar -exec ls -l {} ;\ 

UWAGA: Odstęp między {}i;

Otrzymasz coś takiego:

-rw-r--r--   1 ken admin       181 Jan 27 15:49 /home/ken/foo/bar

Jeśli nie masz pewności, gdzie jest plik, zawsze możesz zmienić lokalizację wyszukiwania. Tak długo, jak ścieżka wyszukiwania zaczyna się od „/”, w zamian otrzymasz ścieżkę bezwzględną. Jeśli szukasz lokalizacji (np. /), W której pojawi się wiele błędów odmowy uprawnień, zalecamy przekierowanie błędu standardowego, abyś mógł zobaczyć wyniki wyszukiwania:

find / -name bar -exec ls -l {} ;\ 2> /dev/null

( 2>to składnia dla powłok Borne i Bash, ale nie będzie działać z powłoką C. Może działać również w innych powłokach, ale wiem tylko na pewno, że działa w Bourne i Bash).


Możesz przekazać wiele argumentów do tego samego lsprocesu za pomocą -exec ls -ld {} +. (Prawdopodobnie nie chcesz -dmieć lszawartości katalogu listy). Albo lepiej, znaleźć zastosowanie wbudowanego w lsz find ... name bar -ls. Ponadto masz niepoprawną składnię dla jednego argumentu na polecenie: musisz zacytować średnik z powłoki, więc tak {} \;.
Peter Cordes,

5

fd

Korzystając z fd(alternatywnie find), użyj następującej składni:

fd . foo -a

Gdzie .jest wzorzec wyszukiwania i fookatalog główny.

Np do listy wszystkich plików w etcrekursywnie, uruchom: fd . /etc -a.

-a, --absolute-path Pokaż ścieżki bezwzględne zamiast względnych


2

Po prostu alternatywa dla

ls -d "$PWD/"* 

aby wskazać, że *jest to rozszerzenie powłoki, więc

echo "$PWD/"*

zrobiłby to samo (wada, której nie można użyć -1do oddzielenia przez nowe wiersze, a nie spacje).


czy możesz rozwinąć więcej na ten temat? co to jest rozszerzenie powłoki? jak korzystać -1z separete po liniach?
Antonio Araujo

@Antonio Araujo, rozszerzenie powłoki to powłoka (np. Bash) zastąpi * listę plików - więcej informacji można znaleźć na stronie podręcznika użytkownika bash. -1 to opcja polecenia ls, echo to inne polecenie, nie ma takich samych opcji.
Marisha

1
lspwd() { for i in $@; do ls -d -1 $PWD/$i; done }

1

Oto przykład, który drukuje listę bez dodatkowego okresu, a także pokazuje, jak wyszukać dopasowanie pliku. Mam nadzieję że to pomoże:

find . -type f -name "extr*" -exec echo `pwd`/{} \; | sed "s|\./||"

1

To zadziałało dla mnie. Ale nie było w porządku alfabetycznym.

find "$(pwd)" -maxdepth 1

To polecenie wyświetla listę alfabetycznie, a także wyświetla ukryte pliki.

ls -d -1 "$PWD/".*; ls -d -1 "$PWD/"*;

1

stat

Bezwzględna ścieżka jednego pliku:

stat -c %n "$PWD"/foo/bar

1

Możesz spróbować tego.

for name in /home/ken/foo/bar/*
do
    echo $name
done

Możesz uzyskać ścieżkę abs za pomocą forpętli i echopo prostu bez find.


0

Jeśli potrzebujesz listy wszystkich plików w bieżącym, a także w podkatalogach

find $PWD -type f

Jeśli potrzebujesz listy wszystkich plików tylko w bieżącym katalogu

find $PWD -maxdepth 1 -type f

0

To da ścieżkę kanoniczną (rozwiąże dowiązania symboliczne): realpath FILENAME

Jeśli chcesz kanoniczną ścieżkę do samego dowiązania symbolicznego, to: realpath -s FILENAME


0

Większość, jeśli nie wszystkie sugerowane metody, dają ścieżki, których nie można użyć bezpośrednio w innym poleceniu terminalu, jeśli ścieżka zawiera spacje. Idealnie byłoby, gdyby wyniki zawierały ukośniki. Działa to dla mnie na macOS:

find / -iname "*SEARCH TERM spaces are okay*" -print 2>&1  | grep -v denied |grep -v permitted |sed -E 's/\ /\\ /g'

-1

find / -print zrobi to


1
... niestety zrobi coś innego (np. wyświetli inne pliki, chyba że zostaną odfiltrowane)
DerMike

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.