Bash: ls * без групування папок


12

Якщо я набираю:

ls source/*

source/fonts:
fontello

source/images:
bg1.png                eng.png        fra.png   

Я отримую список файлів, згрупованих за іменами папок. Як я можу просто отримати список назв файлів?

ls source/*

source/fonts/fontello
source/images/bg1.png
source/images/eng.png
source/images/fra.png   

Спасибі


Якщо це для сценаріїв, ви можете побачити mywiki.wooledge.org/ParsingLs . (Однак, є й способи findнеправильного використання ; особливо, якщо ви біжите for file in $(find ...), ви вдарили по одному з них).
Чарльз Даффі

Відповіді:


13

Здається, це не можливо без зміни виходу, але ось простий альтернативний спосіб:

find source/ -type f

Або (характерно для пошуку GNU), щоб отримати лише файли на глибину вашого запитання:

find source/ -type f -mindepth 2 -maxdepth 2

(або якщо ви хочете, щоб каталоги, як lsдає, видаліть -type f)


5

Ви можете просто дотримуватися ls, якщо додати деякі психічні ( ls -d):

# mkdir test
# cd test
# mkdir A B C
# touch {A,B,C}/file*
# ls -d */*    
A/file  B/file  C/file

@Cthulhu ок, мій приклад занадто короткий, якщо у вас є папки в A, B a / o C, -d допомагає відображати лише те, що ви вибрали. Мені насправді не подобається знайти, і ви можете визначити глибину за допомогою аргументу з ls -d
ikrabbe

Я запропонував редагувати іншу відповідь, щоб обмежити глибину.
o11c

@ o11c дуже добре, але все-таки findє жировим звіром.
ikrabbe

3

Вас може зацікавити "бідняк find":

shopt -s globstar

shopt -s s ets названі параметри (оболонки). globstarПараметр визначається наступним чином в Баш (1) :

Якщо встановлено, шаблон, що **використовується в контексті розширення імені файла / шляху, відповідатиме файлам [sic] та нулю або більше каталогів та підкаталогів. Якщо за шаблоном слідує a /, збігаються лише каталоги та підкаталоги.

Отже, після виконання shopt -s globstarбудь-якої з наступних команд:

ls -d1 - source / **                  # Символ після 'd' є цифрою. 
ls -d - джерело / ** | cat             # тобто запише це в трубу до будь-якої команди. 
printf "% s \ n" джерело / **

дасть вихід:

source/
source/fonts
source/fonts/fontello
source/images
source/images/bg1.png
source/images/eng.png
source/images/fra.png

На жаль, сюди входять і імена каталогів. Можливо, вам це допоможе трохи знати

printf "%s\n" source/**/

дасть вихід:

source/
source/fonts
source/images

тобто лише імена каталогів. Ви можете перенаправити висновок одного з першого набору команд для одного файлу, перенаправити висновок з вище другого файлу, а потім використовувати comm, diffабо що - щось подібне, щоб відняти другий файл з перших, залишивши тільки рівнину файли (не-каталоги). Але не робіть цього.

Ще один підхід (це не набагато краще)

ls -d --file-type -- source/** | grep -v '/$'

Цей --file-typeпараметр повідомляє lsвідображати а / в кінці кожного імені каталогу (та інших символів на кінцях інших (спеціальних) типів файлів), як це:

source //                             # Додано ще одне 
джерело / шрифти / # Додано одне джерело                       
джерело / шрифти / fontello
джерело / зображення /                       # Додано одне
source / images / bg1.png
source / images / eng.png
source / images / fra.png

а потім grep -v '/$'видаляє лінії, які закінчуються /; тобто імена каталогів. На жаль, --file-typeопція не визначена POSIX . Якщо ваша версія lsне підтримує його, використовуйте -F. Це схоже, --file-type за винятком того, що він також відображає *на кінцях імена виконуваних файлів, які деякі люди вважають дратує. Їх можна усунути за допомогою sed:

ls -dF -- source/** | sed -e '/\/$/d' -e 's/\*$//'

Якщо ви хочете зробити щось із усіма файлами (і лише з файлами), ви можете зробити це

для f в джерелі / **
робити
    якщо [-f "$ f"]
    потім
        Вставте команди, які слід застосувати до звичайних файлів.
    фі
зроблено

Примітки:

  • Коли lsвиводиться на термінал, і він не перебуває в -l( l ong) режимі, він записує кілька імен на рядок (якщо тільки імена не дуже довгі). Ви можете змусити його писати одне ім’я на рядок, вказавши -1(одне) або перенаправляючи вихід у файл чи трубу.
  • Напевно, вам не потрібні команди --в lsкомандах, оскільки ви перераховуєте каталог, вміст якого ви створили. Ви повинні використовувати його при переліку *в невідомому каталозі як захист від імен файлів, які починаються з цього -.
  • Не намагайтеся проаналізувати вихід з ls.
  • globstarВаріант оболонки , здається , не визначається POSIX. (Насправді я не впевнений, що POSIX розпізнає будь-які параметри оболонки.) Хоча це, мабуть, є bashism, будьте обережні - він може бути присутнім не у всіх версіях bash.
  • Якщо є fontsабо imagesє підкаталоги, **перерахуйте їх усі, рекурсивно, аж донизу. Один (дещо химерний і ненадійний) спосіб обмеження глибини - це

    ls -d --file-type -- source/** | grep -v '\(/.*\)\{3\}'
    

    який видаляє рядки, що містять три або більше /символів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.