Czy można usunąć prefiks folderu z polecenia `ls`

12

Jestem w skrypcie bash i chcę uzyskać listę wszystkich plików (powiedzmy wszystkie pliki jar). Wykonuję polecenie ls -1 lib/*.jari otrzymuję wynik:

lib/mylib_1.jar
lib/mylib_2.jar
...

Czy jest jakaś opcja, aby uzyskać następujące dane wyjściowe:

mylib_1.jar
mylib_2.jar
...

Tworzenie cd libwcześniej nie jest opcją, ponieważ jestem w pętli i muszę znajdować się w folderze nadrzędnym, aby wykonać czynności, które chcę wykonać w pętli.

Próbowałem znaleźć informacje, pisząc na maszynie, man lsale nie znalazłem żadnego rozwiązania.

Rozwiązanie z innym poleceniem byłoby dobre, pod warunkiem, że mogę potokować je do mojego lspolecenia lub samowystarczalne.

рüффп
źródło
Co robisz z nazwami tych plików? Po prostu wyświetlasz je na terminalu, czy przekazujesz je do innego programu lub skryptu (indywidualnie lub jako listę)? Prawidłowy sposób radzenia sobie z tym zależy od sposobu używania nazw plików.
Kusalananda
Pomysł polegał na zrobieniu statystyk dotyczących bibliotek stron trzecich w wielomodułowym projekcie Java. Chciałem tylko zrobić listę i zrobić coś po raz pierwszy
рüффп

Odpowiedzi:

19

Zamiast analizować ls powinieneś użyć findzamiast tego. Następnie możesz również wykonać basenamedla każdego pliku, aby usunąć wiodące katalogi:

find lib/ -name '*.jar' -exec basename {} \;
Josh Jolly
źródło
Ok, ten sposób jest również idealny dla mnie.
рüффп
3
Zobacz także -maxdepthopcję.
13

Dzięki GNU findnie trzeba uruchamiać basenamekażdego pliku, będzie to znacznie szybsze (szczególnie jeśli jest dużo plików):

find lib -name '*.jar' -printf '%P\n'
Graeme
źródło
11

Co powiesz na to (cd lib && echo *.jar), zakładając, że w nazwach plików nie ma białych znaków ani znaków specjalnych. Skrypt nadrzędny nigdy nie zmienia katalogu.

doneal24
źródło
Spacje też nie będą stanowić problemu.
terdon
To dobry pomysł i prawdopodobnie będzie najszybszą opcją. Zrobiłbym jednak, printf '%s\n' *.jaraby każdy plik znalazł się w innej linii.
Graeme
Lub nawet w printf '%s\0' *.jarcelu wyeliminowania problemów z białymi znakami (chociaż nie jest to Q).
Graeme
5

Jak powiedział Josh Jolly w swojej odpowiedzi, nigdy nie powinieneś parsować ls, zamiast tego użyj podejścia z jego odpowiedzi. Mimo to oto awkrozwiązanie do usuwania ścieżek z nazw plików, po prostu nie używaj go z ls:

find . | awk -F'/' '{print $NF}'

Te -F'/'zestawy separator pola do /co oznacza, że ostatnie pole, $NFbędzie nazwa pliku.

terdon
źródło
1

findprawdopodobnie jest droga, ale jeśli naprawdę zrobić (nie) chce zdejmować lib/z ls -1, można użyć sed:

$ ls -1 lib/*.jar | sed 's#^lib/##'
mylib_1.jar
mylib_2.jar

źródło
0

Możesz to zrobić za pomocą xargs z parametrem --max-args (lub krótszym aliasem -n):

ls --quoting-style=c -1 lib/*.jar | xargs --max-args 1 basename ls --quoting-style=c -1 lib/*.jar | xargs -n 1 basename

Zauważ, że używamy, --quoting-style=caby upewnić się, że spacje w nazwach plików nie psują xargs.

yoni
źródło
Nie zauważyłem tego. Dziękuję Ci! Znalazłem ten klejnot na innej giełdzie stosów. Możesz wprowadzić cudzysłowy do wyników ls za pomocą --quoting-style = c. Zatem wynikowe pełne polecenie brzmiałoby: `ls --quoting-style = c -1 lib / *. Jar | xargs --max-args 1 basename`
yoni
-1

Alternatywnym sposobem rozwiązania zapytania jest wyświetlenie listy wszystkich używanych plików ls -R. Połącz dane wyjściowe polecenia ls z grep, aby wyświetlić tylko pliki .jar. Możesz użyć następującego polecenia, aby zrobić to samo dla zapytania:

ls -R lib | grep jar| grep -v jar*
joshi.mohit86
źródło
Nie udałoby się to źle, gdyby istniał podkatalog zawierający pliki jar lub plik o nazwie na przykład „list-of-jars.txt”.
Jules
grep -v jar * odfiltruje wyniki z plikiem o nazwie podobnej do cytowanego przykładu.
joshi.mohit86
prawdziwe. odfiltruje również wszystkie zamierzone pliki. Teraz patrzę na to jeszcze raz, nie widzę żadnych okoliczności, w których sugerowane przez ciebie polecenie w ogóle dałoby jakiekolwiek wyjście ...
Jules,
Nie, wyświetla pliki takie jak mylib_2.jari odfiltrowuje pliki takie jak list-of-jars.txt.
joshi.mohit86
Nie, nie ma. Właśnie tego spróbowałem. find development -name '*.jar' | wc -l-> 70. ls -R development | grep jar| grep -v jar*-> brak wyjścia.
Jules