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.

dreftymac
źródło
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 }'
ghostdog74
źródło
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
stefanB
źródło
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 .)

inni
źródło
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"
Ivan Alegre
źródło
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
kerkael
źródło
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"
Ojciec chrzestny
źródło
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 *.

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

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

Rob D.
źródło
1
jakiś pomysł, jak mogę usunąć rozmiar pliku bez awk?
Arnold Roa,
12

znajdź / zrobi lewę

Dmitry
źródło
10

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

ls -lR /path/I/need
KellyC
źródło
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ł ...

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

Mając swobodę korzystania ze wszystkich możliwych opcji ls:

find -type f | xargs ls -1

Grzegorz Luczywo
źródło
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
Dimitrios
źródło
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 \{\} \;
Denio Mariz
źródło
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.

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

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

Steve
źródło
4

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

sivi
źródło
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
John Keyes
źródło
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 "/$"          
Reguła B.
źródło
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]
Chaitanya
źródło
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

hpj
źródło