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?

Rozpoznać
źródło
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.

Matthew Scharley
źródło
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ę.

balki
źródło
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.

użytkownik431529
źródło
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

Vinko Vrsalovic
źródło
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.

czy ja
źródło
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
GSM
źródło
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.

Gurpreet
źródło
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).

Trudius
źródło
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

kenorb
źródło
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).

Marisha
źródło
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 }
rxw
źródło
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|\./||"
Mike Behr
źródło
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/"*;
Raveen Kumar
źródło
1

stat

Bezwzględna ścieżka jednego pliku:

stat -c %n "$PWD"/foo/bar
kenorb
źródło
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.

fangxl mr
źródło
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
Thyag
źródło
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

JGurtz
źródło
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'
Adam
źródło
-1

find / -print zrobi to

David Arno
źródło
1
... niestety zrobi coś innego (np. wyświetli inne pliki, chyba że zostaną odfiltrowane)
DerMike
-1
ls -1 | awk  -vpath=$PWD/ '{print path$1}'
Albert
źródło