Чи можливо видалити префікс папки з команди `ls`


12

Я в скрипті bash і хочу отримати список усіх файлів (скажімо, всі файли jar). Я виконую команду ls -1 lib/*.jarі отримую вихід:

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

Чи є варіант мати такий вихід:

mylib_1.jar
mylib_2.jar
...

Здійснення cd libраніше - це не варіант, оскільки я перебуваю в циклі, і мені потрібно знаходитись у батьківській папці для дій, які я хочу зробити всередині циклу.

Я намагався знайти інформацію, ввівши, man lsале не знайшов рішення.

Рішення з іншою командою було б добре, доки я можу передати його своїй lsкоманді або самодостатній.


Що ви робите з іменами цих файлів? Ви просто перераховуєте їх до терміналу чи передаєте їх іншій програмі чи сценарію (окремо або як список)? Правильний спосіб вирішення цього питання залежить від того, як використовуються назви файлів.
Kusalananda

Ідея полягала в тому, щоб провести деяку статистику щодо сторонніх ліб на багатомодульному проекті Java. Я просто хотів список і зробити сорт і
uniq

Відповіді:


19

Замість розбору ls слід використовувати findзамість цього. Тоді ви також можете виконати basenameна кожному файлі, щоб зняти провідні каталоги:

find lib/ -name '*.jar' -exec basename {} \;

Ок, цей спосіб ідеально підходить і для мене.
рüффп

3
Також дивіться -maxdepthваріант.

13

З GNU findне потрібно запускати basenameкожен файл, це буде набагато швидше (особливо якщо файлів багато):

find lib -name '*.jar' -printf '%P\n'

11

Як щодо (cd lib && echo *.jar), якщо припустити, що у назвах файлів немає пробілів або спеціальних символів. Батьківський скрипт ніколи не змінює каталог.


Пробіли також не будуть проблемою.
terdon

Це гарна ідея і, мабуть, буде найшвидшим варіантом. Я б хотів, printf '%s\n' *.jarщоб кожен файл перейшов у інший рядок.
Graeme

Або навіть printf '%s\0' *.jarусунути проблеми з пробілами (хоча це не Q).
Graeme

5

Як сказав Джош Джоллі у своїй відповіді, ви ніколи не повинні розбиратися ls, а використовувати підхід у своїй відповіді. Тим не менш, ось awkрішення для видалення шляхів з імен файлів, просто не використовуйте його з ls:

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

У -F'/'наборах роздільник поля /означає , що останнє поле, $NFбуде мати ім'я файлу.


1

findце, мабуть, шлях, але якщо ви дійсно, дійсно (не хочете) знімати lib/з себе ls -1, ви можете використовувати sed:

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

0

Це можна зробити за допомогою xargs з параметром --max-args (або коротшим псевдонімом -n):

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

Зауважте, що ми використовуємо --quoting-style=cдля того, щоб пробіли у назви файлів не видаляли xargs.


Я цього не помічав. Дякую! Знайдено цей самоцвіт на іншій біржі стеків. Ви можете ввести цитати до результатів ls за допомогою --quoting-style = c. Отже, отримана повна команда буде: `ls --quoting-style = c -1 lib / *. Jar | xargs --max-арг 1 basename`
йоні

-1

Альтернативний спосіб вирішити ваш запит - перерахувати всі файли, які використовуються ls -R. Комбінуйте вихід команди ls з grep, щоб перелічити лише файли .jar. Ви можете використовувати наступну команду, щоб зробити те ж саме для вашого запиту:

ls -R lib | grep jar| grep -v jar*

Це погано вийде, якби був підкаталог, який також містить jar-файли, або файл, названий, наприклад, "list-of-jars.txt".
Жуль

grep -v jar * фільтрує результати з файлу, названого як ваш цитований приклад.
joshi.mohit86

правда. він також фільтрував би всі призначені файли. Тепер я знову дивлюся на це, я не бачу жодних обставин, коли команда, яку ви пропонуєте, насправді взагалі не дала б результатів ...
Жюль,

Ні, він відображатиме такі файли, як mylib_2.jarі фільтрує такі файли list-of-jars.txt.
joshi.mohit86

Ні, це не так. Я просто спробував це. find development -name '*.jar' | wc -l-> 70. ls -R development | grep jar| grep -v jar*-> відсутній взагалі.
Жуль
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.