Перелічіть лише звичайні файли (але не каталоги) у поточному каталозі


126

Я можу використовувати, ls -ld */щоб перерахувати всі записи каталогів у поточному каталозі. Чи існує подібний простий спосіб просто перерахувати всі звичайні файли в поточному каталозі? Я знаю, що можу використовувати знахідку

find . -maxdepth 1 -type f

або stat

stat -c "%F %n" * | grep "regular file" | cut -d' ' -f 3-

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


5
Що ви маєте на увазі під "надмірно елегантним"? Наскільки я знаю, findкоманда - це найкращий спосіб робити те, що ти хочеш. Для деяких надійних інших параметрів вам слід ознайомитись з командними специфічними командами (і це все, крім портативного)!
rahmu

@rahmu Я був для чогось схожого на ls -d */, яке є коротким, легким для набору та легким для розуміння. Тож я дуже задоволений відповіддю Ульріха Дангеля, хоча я не використовую zsh.
Даніель Куллманн

Відповіді:


32

Кваліфікатори за допомогою zshта Glob ви можете легко висловити це безпосередньо, наприклад:

echo *(.)

поверне лише список звичайних файлів або помилку залежно від конфігурації.

Для не-каталогів:

echo *(^/)

(включатиме символьні посилання (включаючи каталоги), названі труби, пристрої, розетки, двері ...)

echo *(-.)

для звичайних файлів і посилань на звичайні файли.

echo *(-^/)

для не-каталогів, і немає посилань на каталоги.

Крім того, див. DКласифікатор глобалізації, якщо ви хочете включити файли D (приховані файли), наприклад *(D-.).


170
ls -p | grep -v / 

Ця команда перераховує всі не приховані файли, які не є каталогами (звичайні файли, посилання, файли пристроїв тощо). Щоб також включити приховані файли, додайте -Aпараметр доls

Він передбачає, що жоден з файлів не містить символів нового рядка у своєму імені. Додавання -qпараметра для lsтрансформації всіх символів, що не надруковані, включаючи новий рядок ?, гарантуючи, що вони знаходяться на одній лінії та настільки придатні для подачі на лінійну утиліту, як grepі для друку на терміналі.


14
+1, це хороша відповідь. Відмовившись від голосування, новий користувач без коментарів мене дуже шокує, особливо коли надається робоча відповідь. Єдиний крайовий випадок, за яким я бачу, де це не працюватиме належним чином, якщо в назви файлу є новий рядок. Також збереження кольорів буде приємним доповненням, коли воно підтримується. Для GNU ви можете додати --color=alwaysдо ls, для OSX -G.
Graeme

Привіт, команда, яку ви дали, чудова, і це, безумовно, допомагає мені, однак мені було цікаво, чи можна використовувати вищевказану команду і одночасно змінити дозвіл на файл? Я спробував додати в sudo chmod 777кінці, і мені дали помилки ... Будь-яка допомога дуже вдячна
dissidia

3
Якщо ви також хочете виключити посилання, які вказують на каталоги ls -pL | grep -v /. -LСимвольні посилання, що додаються, відновлення.
Маттіас Браун

1
Якщо вам також подобається використовувати фільтр підстановки, зробіть це ls -pdL something* | grep -v /. Додана -dопція перераховує самі каталоги, а не їх вміст, тому вони будуть виключені правильно.
Rockallite

І якщо ви хотіли захопити всі файли без папок, просто видаліть -v
jasonleonhard

23

Щоб переглянути лише звичайні файли:

ls -al | grep '^-'

З включеними символічними посиланнями (на будь-який тип файлу):

ls -al | grep '^[-l]'

Де перший символ списку описує тип файлу, -значить, це звичайний файл, для символічного посилання є l.

Debian / Ubuntu

Роздрукуйте імена всіх відповідних файлів (включаючи посилання):

run-parts --list --regex . .

З абсолютними шляхами:

run-parts --list --regex . "$PWD"

Роздрукуйте імена всіх файлів, /etcщо починаються з pі закінчуються d:

run-parts --list --regex '^p.*d$' /etc

15

lsне має можливості цього робити, але одна з приємних речей про unix & linux - це те, що довгомоторні та неелегантні конвеєри можуть бути легко перетворені в сценарій, функції або псевдонім оболонки. і вони, в свою чергу, можуть бути використані в трубопроводах, як і будь-яка інша програма.

(ПРИМІТКА. Існують деякі проблеми сфери застосування функцій та псевдонімів. Сценарії доступні будь-якому виконуваному файлу, який може їх читати та виконувати. Псевдоніми та функції доступні лише в поточній оболонці, хоча програму .profile / .bashrc і т.д. може переробити. і, таким чином, зробити їх доступними. Крім того, сценарій можна писати будь-якою мовою - включаючи bash / sh, awk, perl, python та інші - в залежності від того, який з них найкраще підходить для роботи або який вам найбільше знайомий)

напр

alias lsf='find . -maxdepth 1 -type f -print0 | xargs -0r ls'

Я додав xargs, щоб ви могли використовувати всі звичні lsпараметри, наприкладlsf -lrS

Оскільки він використовується find, всі нормально приховані точкові файли будуть показані, а всі назви файлів будуть встановлені з допомогою префікса ./ - це лише єдина різниця, яку ви помітите.

Ви можете виключити точкові файли за допомогою, ! -iname '.*'але тоді вам доведеться мати дві версії псевдоніму - таку, яка відображає крапкові файли, та одну, яка не має.

alias lsf2='find . -maxdepth 1 -type f -a ! -iname '\''.*'\'' -print0 | xargs -0r ls'

Крім того, якщо це lsfбув сценарій, а не псевдонім, ви можете проаналізувати параметри (можливо, за допомогою getopts або / usr / bin / getopt або подібних) і виключити dotfiles, якщо -aнемає.


-nameдостатньо, вам не потрібно -iname.
Тотор

8
bash-4.2$ ls -F | grep -v '[/@=|]$' | more

Опція -F до ls додає * до виконуваних файлів, / до каталогів, @ до символічних посилань, = до сокетів та | до ФІФО. Потім ви можете використовувати grep, щоб виключити нерегулярні символи файлу з виводу, і у вас є файли. Це працюватиме в будь-якій оболонці, а не лише zsh.

Слабкі сторони:

  1. Будь-який файл, чиє ім’я закінчується @, =або |буде виключений (але ви дійсно не повинні мати файли з тими символами в імені)
  2. Це не виключає файлів пристроїв або деяких екзотичних типів файлів у деяких системах, таких як двері.
  3. У будь-якому файлі, який виконується, додається зірочка. З цим можна вирішити, провівши через sed, щоб видалити будь-які символи '*' з виводу.
  4. Це не працює належним чином, якщо є імена файлів, що містять символи нового рядка.

Про систему я пишу це на 10% файли мають імена , що містять =, @або |символи. =є поширеним у maildir або назви файлів, які мають закодовану частину base64 або кодовану цитатами. @у локальних визначеннях, для електронних адрес тощо. Хоча вони рідко з’являються в кінці імені файлу. (наприклад, у цій системі 31 із 2,2 мільйона)
Stéphane Chazelas

3

У посібнику вказано, що параметр 'f' протилежний лише «звичайного файлу», а не труб, розеток чи блокових / зарядних пристроїв, а значить, ви вже робите потрібні речі.

   -type c
          File is of type c:

          b      block (buffered) special

          c      character (unbuffered) special

          d      directory

          p      named pipe (FIFO)

          f      regular file

          l      symbolic link; this is never true if the -L option or the
                 -follow option is in effect, unless the symbolic link  is
                 broken.  If you want to search for symbolic links when -L
                 is in effect, use -xtype.

          s      socket

          D      door (Solaris)

0

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

for list in `ls` ; do ls -ld $list | grep -v ^d > /dev/null && echo $list ; done ;

Ви можете перетворити греп і умовний вихід, такі самі результати:

for list in `ls` ; do ls -ld $list | grep ^d > /dev/null || echo $list ; done ;

\dev\null?!?!
манатство


0

Це трохи стара тема, але найчистіший спосіб переліку лише файлів.

ls -al | grep '^-' | awk '{print $9}'


1
touch "some file name"щоб побачити швидкий контрприклад
Jeff Schaller

@JeffSchaller У вас є дійсна точка. Для цього щось подібне. ls -al | grep '^-' | awk '{ for(i=9; i<=NF; ++i) printf $i""FS; print "" }', повинен обробляти файли з пробілами в них.
RJ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.