Polecenie ls: jak mogę uzyskać rekursywną listę z pełną ścieżką, jeden wiersz na plik?


493

Jak zmusić ls do wyplucia płaskiej listy ścieżek rekurencyjnych jeden na linię?

Na przykład chcę tylko płaską listę plików z ich pełnymi ścieżkami:

/home/dreftymac/.
/home/dreftymac/foo.txt
/home/dreftymac/bar.txt
/home/dreftymac/stackoverflow
/home/dreftymac/stackoverflow/alpha.txt
/home/dreftymac/stackoverflow/bravo.txt
/home/dreftymac/stackoverflow/charlie.txt

ls -a1 prawie robi to, czego potrzebuję, ale nie chcę fragmentów ścieżek, chcę pełne ścieżki.


Zobacz także: drzewo
— dreftymac

Odpowiedzi:


386

Jeśli naprawdę chcesz użyć ls, sformatuj dane wyjściowe za pomocą awk:

ls -R /path | awk '
/:$/&&f{s=$0;f=0}
/:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
NF&&f{ print s"/"$0 }'

5
@dreftymac, co oznacza, że ​​jest to obiektywnie właściwa odpowiedź na pytanie, które napisałeś celowo lub nie. Tak, być może nie była to właściwa odpowiedź na pytanie, który miał nadzieję , że napisane. I chociaż zgadzam się z twoim większym punktem: „kiedy mądry wskazuje na księżyc, głupiec patrzy na palec”, to sprawiedliwe, że minimalizujemy wpływ subiektywności na ocenę poprawności, szczególnie gdy kryteria nie są w żaden sposób dwuznaczne
— lurscher

1
@dreftymac, chętnie zmienię mój głos, ale jest on teraz zablokowany, musisz edytować pytanie, aby móc zaktualizować głos
— lurscher 15.04.2013

7
Czy ktoś może wyjaśnić powyższe awkwyrażenia?
— Mert Nuhoglu,

2
To rozwiązanie nie pomija katalogów (każdy katalog ma własną linię)
— JayB

2
Dzięki. Przy okazji, byłoby miło mieć to w 1 linii do szybkiego kopiowania i wklejania.
— Leo Ufimcew

567

Użyj znajdź:

find .
find /home/dreftymac

Jeśli chcesz tylko pliki (pomiń katalogi, urządzenia itp.):

find . -type f
find /home/dreftymac -type f

2
czy lsparametry takie jak --sort=extension„zrealizowane” przez to rozwiązanie?
— n611x007

Możesz nawet użyć danych wyjściowych printf, aby wyświetlić potrzebne informacje kontekstowe (np. Znajdź. -Type f -printf '% p% u \ n')
— xsubira 14.0415

Czy można to sformatować za pomocą falga? to znaczy. python pprint.pprint (pliki)
— Nathan

72

ls -ld $(find .)

jeśli chcesz posortować dane wyjściowe według czasu modyfikacji:

ls -ltd $(find .)


11
-bash: / bin / ls: Zbyt długa lista argumentów
— jperelli

1
+1 działało dla mnie z 12106 plikami i mogłem użyć --sort=extensionparametruls
— n611x007

3
Dzięki. Sam bym nie pomyślał o tej (ładnej i krótkiej) składni - użyłbym find . -name "*" -exec ls -ld '{}' \;(że działa niezależnie od liczby plików), ale twoje polecenie jest o wiele krótsze do napisania;)
— SRG

1
ls -ld $ (find.) psuje się, jeśli wyświetlam dysk NTFS, na którym pliki mają spacje: ls: nie można uzyskać dostępu ./System: nie ma takiego pliku lub katalogu, ale można znaleźć cytaty autorstwa @SRG
— kuz8

Byłaby krótsza alternatywa (w zależności od potrzeb) find . -ls.
— IanS

59

Wypróbuj następujący prostszy sposób:

find "$PWD"

9
find "`pwd`"jeśli ścieżka zawiera spacje lub inne znaki specjalne.
— mustafa.0x

7
Czym to się różni find .? -.-
— Salman von Abbas,

7
@ SalmanPK Jeśli podasz znaleźć ścieżkę bezwzględną, jak pwdna początek, wydrukuje ścieżki bezwzględne. Nawiasem mówiąc: „Jak to się różni od find” ;-)
— yckart

44

Najlepsze polecenie to: tree -fi

Aby użyć plików, ale nie łączy, musisz usunąć >z wyników:

tree -fi |grep -v \>

Jeśli chcesz poznać charakter każdego pliku (na przykład tylko do odczytu plików ASCII) za pomocą dwóch whiles:

tree -fi | \
grep -v \> | \
while read first ; do 
    file ${first}
done | \
while read second; do 
    echo ${second} | grep ASCII
done

Dziękuję, nie wiedziałem o tree!
— Dan Filimon

@Nakilon, co jest najbliższe? Czy wyświetla podobnie wyjście? Jak łatwo wyświetlać podobne wyniki za pomocą krótkiego polecenia?
— om01

6
@ om01: na OSX jest to trudne brew install tree, ponieważ używasz homebrew
— ccpizza

nie mogłem wymienić plików na wyłączność. zawsze zawiera także katalogi. jak mogę to zrobić?
— kommradHomer

To powinno być ocenione znacznie wyżej!
— der_grund

44

Och, naprawdę długa lista odpowiedzi. Bardzo mi pomogło, a na koniec stworzyłem własny, którego szukałem:

Aby wyświetlić listę wszystkich plików w katalogu i jego podkatalogach:

find "$PWD" -type f

Aby wyświetlić listę wszystkich katalogów w katalogu i jego podkatalogach:

find "$PWD" -type d

Aby wyświetlić listę wszystkich katalogów i plików w katalogu i jego podkatalogach:

find "$PWD"

2
I filtrowanie według rozszerzenia:find "$PWD" -type f | grep '\.json$'
— Killroy

2
Nie ma potrzeby przetwarzania końcowego za pomocą grep, użyj -name w find jak: znajdź „$ PWD” -typ f -name * .json i jeśli chcesz usunąć wymienione pliki: znajdź „$ PWD” -typ f-name * .json -exec rm {} \; podobnie, jeśli chcesz go skopiować, zamień rm na cp i destination: -exec cp {} destination
— Ojciec chrzestny

18

Nie wiem o pełnej ścieżce, ale możesz użyć jej -Rdo rekurencji. Alternatywnie, jeśli nie masz ochoty ls, możesz po prostu to zrobić find *.


16

Nie używając zewnętrznych poleceń innych niż ls:

ls -R1 /path | 
  while read l; do case $l in *:) d=${l%:};; "") d=;; *) echo "$d/$l";; esac; done


Nieznana opcja „-1”. Przerwanie.
— ilw

15
du -a

Przydatne w przypadku niektórych ograniczonych powłok urządzenia, w których funkcja znajdowania / lokalizowania nie jest dostępna.


1
jakiś pomysł, jak mogę usunąć rozmiar pliku bez awk?
— Arnold Roa,


10

Nie komplikuj tego. Właśnie tego użyłem i uzyskałem piękny wynik:

ls -lR /path/I/need

3
OP chce tylko pełnej ścieżki i nic więcej. ls -lRnie osiągnąłby tego celu.
— codeforester

przepraszam, to nie robi
— Aryeh Beitz

9

Najłatwiejszym sposobem dla wszystkich przyszłych ludzi jest po prostu:

du

Pokazuje to jednak również rozmiar zawartości każdego folderu. Możesz użyć awk, aby wyświetlić tylko nazwę folderu:

du | awk '{print $2}'

Edytuj- Przepraszam, mój zły. Myślałem, że potrzebne były tylko foldery. Zostawię to tutaj, na wypadek gdyby ktoś w przyszłości i tak tego potrzebował ...


Interesujące, ponieważ pokazuje mi rzeczy, o których nie wiedziałem, że chcę wiedzieć - coś w rodzaju Google. Okazuje się, że lubię wiedzieć, ile miejsca zajmuje każdy plik.
— Jake Toronto


9

Myślę, że dla płaskiej listy najlepszym sposobem jest:

find -D tree /fullpath/to-dir/ 

(lub w celu zapisania go w pliku txt)

find -D tree /fullpath/to-dir/ > file.txt

3
Próbowałem na Mac OS 10.13.3. find: illegal option -- D
— Jayant Bhawal

8

Uruchom polecenie bash w następującym formacie:

find /path -type f -exec ls -l \{\} \;

6

Oto częściowa odpowiedź, która pokazuje nazwy katalogów.

ls -mR * | sed -n 's/://p'

Wyjaśnienie:

ls -mR * wyświetla pełne nazwy katalogów kończące się na „:”, a następnie osobno wyświetla pliki w tym katalogu

sed -n 's/://p' znajduje linie kończące się dwukropkiem, zdejmuje je z jelita i drukuje linię

Powtarzając listę katalogów, powinniśmy również móc znaleźć katalogi. Nadal nad tym pracuję. Przebijanie symboli wieloznacznych przez xargs jest wyzwaniem.


świetna odpowiedź .. dokładnie to, czego potrzebowałem!
— Selvin

5

Dodanie symbolu wieloznacznego na końcu katalogu ls wymusza pełne ścieżki. Teraz masz to:

$ ls /home/dreftymac/
foo.txt
bar.txt
stackoverflow
stackoverflow/alpha.txt
stackoverflow/bravo.txt
stackoverflow/charlie.txt

Zamiast tego możesz to zrobić:

$ ls /home/dreftymac/*
/home/dreftymac/.
/home/dreftymac/foo.txt
/home/dreftymac/bar.txt
/home/dreftymac/stackoverflow:
alpha.txt
bravo.txt
charlie.txt

Niestety nie drukuje to pełnej ścieżki do katalogów, w których ponownie się znajdują, więc może nie być to pełne rozwiązanie, którego szukasz.


Niestety, nie można sudo ls z symbolem wieloznacznym (ponieważ symbol wieloznaczny jest rozwijany jako zwykły użytkownik).
— andrew lorien

4

Widzę wiele odpowiedzi. To jest moje i myślę, że całkiem przydatne, jeśli pracujesz na Macu.

Jestem pewien, że wiesz, że istnieją pewne pliki „pakietowe” ( .app , .rtfd , .workflow itd.). I patrząc w okno Findera wydają się pojedynczymi plikami. Ale nie są. I $ lsalbo $ findzobacz je jako katalogi ... Więc jeśli nie potrzebujesz też listy ich zawartości, działa to dla mnie:

find . -not -name ".*" -not -name "." | egrep -v "\.rtfd/|\.app/|\.lpdf/|\.workflow/"

Oczywiście dotyczy to działającego katalogu i można dodawać rozszerzenia innych pakietów (ale zawsze /po nich). Lub dowolne inne rozszerzenia, jeśli nie są pakietami bez/ .

Raczej interesujące „ .lpdf/” (wielojęzyczny pdf). Ma normalne .pdfrozszerzenie (!!) lub brak w Finderze. W ten sposób dostajesz (lub liczy tylko 1 plik) za to, pdfa nie kilka rzeczy…


4

ls -lR tego właśnie szukałeś, a przynajmniej ja byłem. Twoje zdrowie


OP chce tylko pełnej ścieżki i nic więcej. ls -lRnie osiągnąłby tego celu.
— Hadrien TOMA

3

Jeśli katalog zostanie przekazany jako ścieżka względna, przed wywołaniem funkcji find należy go przekonwertować na ścieżkę bezwzględną. W poniższym przykładzie katalog jest przekazywany jako pierwszy parametr do skryptu:

#!/bin/bash

# get absolute path
directory=`cd $1; pwd`
# print out list of files and directories
find $directory

Jeśli masz system, readlinkmożesz to zrobićdirectory=$(readlink -e $1)
— wstrzymano do odwołania.

To prawda, ale kombinacja cd / pwd będzie działać na każdym systemie. readlinkw systemie OS X 10.5.8 nie obsługuje opcji -e.
— John Keyes,

3
tar cf - $PWD|tar tvf -             

Jest to powolne, ale działa rekurencyjnie i drukuje zarówno katalogi, jak i pliki. Możesz potokować go za pomocą awk / grep, jeśli chcesz tylko nazwy plików bez wszystkich innych informacji / katalogów:

tar cf - $PWD|tar tvf -|awk '{print $6}'|grep -v "/$"          

2
możesz także użyć po prostu: tar cvf / dev / null $ PWD
— RuleB 14.09.13

2

@ ghostdog74: Mała modyfikacja rozwiązania.
Poniższy kod może być wykorzystany do wyszukiwania pliku z pełną ścieżką bezwzględną.

sudo ls -R / | awk '<br/>
/:$/&&f{s=$0;f=0}<br/>
/:$/&&!f{sub(/:$/,"");s=$0;f=1;next}<br/>
NF&&f{ print s"/"$0 }' | grep [file_to_search]

1

Znałem nazwę pliku, ale chciałem również katalog.

znajdź $ PWD | fgrep nazwa pliku

działał doskonale w Mac OS 10.12.1

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.