Можно ли удалить префикс папки из команды `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команде или самодостаточно.

рüффп
источник
Что вы делаете с именами этих файлов? Вы просто перечисляете их в терминал или передаете их другой программе или сценарию (по отдельности или в виде списка)? Правильный способ справиться с этим зависит от того, как используются имена файлов.
Кусалананда
Идея заключалась в том, чтобы сделать статистику о сторонних библиотеках в многомодульном Java-проекте. Я просто хотел список и сделать сортировку и уникальность после
рюффп

Ответы:

19

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

find lib/ -name '*.jar' -exec basename {} \;
Джош Джолли
источник
Хорошо, этот способ идеально подходит и для меня.
рüффп
3
Также см. -maxdepthВариант.
13

В GNU findнет необходимости запускать basenameкаждый файл, это будет намного быстрее (особенно, если файлов много):

find lib -name '*.jar' -printf '%P\n'
Graeme
источник
11

Как насчет того (cd lib && echo *.jar), чтобы в именах файлов не было пробелов или специальных символов? Родительский скрипт никогда не меняет каталог.

doneal24
источник
Пробелы тоже не будут проблемой.
Тердон
Это хорошая идея и, вероятно, будет самым быстрым вариантом. Я хотел бы сделать, printf '%s\n' *.jarчтобы каждый файл в отдельной строке, хотя.
Грэм
Или даже printf '%s\0' *.jarдля устранения проблем с пробелами (хотя это не вопрос).
Грэм
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*
joshi.mohit86
источник
Это может плохо работать, если существует подкаталог, который также содержит файлы 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*-> нет вывода вообще.
Жюль