Команда ls: как мне получить рекурсивный полный путь, по одной строке на файл?


493

Как я могу заставить ls выдавать плоский список рекурсивных путей по одной строке?

Например, я просто хочу плоский список файлов с их полными путями:

/home/dreftymac/.
/home/dreftymac/foo.txt
/home/dreftymac/bar.txt
/home/dreftymac/stackoverflow
/home/dreftymac/stackoverflow/alpha.txt
/home/dreftymac/stackoverflow/bravo.txt
/home/dreftymac/stackoverflow/charlie.txt

ls -a1 почти делает то, что мне нужно, но я не хочу фрагменты пути, я хочу полные пути.


Смотрите также: дерево
dreftymac

Ответы:


386

Если вы действительно хотите использовать ls, то отформатируйте вывод, используя awk:

ls -R /path | awk '
/:$/&&f{s=$0;f=0}
/:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
NF&&f{ print s"/"$0 }'

5
@dreftymac, что означает, что это, объективно говоря, правильный ответ на вопрос, который вы написали, намеренно или нет. Да, возможно, это был не правильный ответ на вопрос, который вы надеялись написать. И хотя я согласен с вашей более важной точкой: «когда мудрый указывает на луну, дурак смотрит на палец», будет справедливо, что мы минимизируем влияние субъективности для оценки правильности, особенно когда критерии не имеют никакой возможной двусмысленности
Lurscher

1
@dreftymac, я буду рад изменить свой голос, но теперь он заблокирован, вам нужно отредактировать вопрос, чтобы я мог обновить голосование
lurscher

7
Может кто-нибудь объяснить, пожалуйста, вышеприведенные awkвыражения?
Мерт Нухоглу

2
Это решение не пропускает каталоги (каждый каталог получает свою собственную строку)
JayB

2
Спасибо. Кстати, было бы неплохо иметь это в 1 строку для быстрого копирования и вставки.
Лев Уфимцев

567

Используйте find:

find .
find /home/dreftymac

Если вам нужны только файлы (не указывайте каталоги, устройства и т. Д.):

find . -type f
find /home/dreftymac -type f

2
могут ли lsпараметры типа --sort=extension"выкупить" этим решением?
n611x007

Вы даже можете использовать вывод printf для отображения необходимой контекстной информации (например, find. -Type f -printf '% p% u \ n')
xsubira

Можно ли это отформатировать с помощью Falg? то есть. Python pprint.pprint (файлы)
Натан

72

ls -ld $(find .)

если вы хотите отсортировать вывод по времени модификации:

ls -ltd $(find .)


11
-bash: / bin / ls: список аргументов слишком длинный
jperelli

1
+1 работал у меня с 12106 файлами, и я мог использовать --sort=extensionпараметрls
n611x007

3
Спасибо. Я бы не подумал об этом (хорошем и коротком) синтаксисе - я бы использовал find . -name "*" -exec ls -ld '{}' \;(этот работает независимо от количества файлов), но ваша команда намного короче для записи;)
SRG

1
ls -ld $ (find.) ломается для меня, если я перечисляю диск ntfs, где у файлов есть пробелы: ls: нет доступа ./System: Нет такого файла или каталога, однако поиск с кавычками @SRG работает
kuz8

Более короткая альтернатива (в зависимости от ваших потребностей) будет find . -ls.
Янв

59

Попробуйте следующий более простой способ:

find "$PWD"

9
find "`pwd`"если путь содержит пробелы или некоторые другие специальные символы.
mustafa.0x

7
Чем это отличается от find .? -.-
Салман фон Аббас

7
@SalmanPK Если вы укажете для поиска абсолютный путь, например pwd, он выведет абсолютные пути. Кстати, "Чем это отличается от find" ;-)
yckart

44

Лучшая команда это: tree -fi

Чтобы использовать файлы, но не ссылки, вы должны удалить >из вывода:

tree -fi |grep -v \>

Если вы хотите знать природу каждого файла (например, для чтения только файлов ASCII) с двумя whiles:

tree -fi | \
grep -v \> | \
while read first ; do 
    file ${first}
done | \
while read second; do 
    echo ${second} | grep ASCII
done

Спасибо, я не знал о tree!
Дан Филимон

@ Накилон, что самое близкое? Он отображает вывод аналогично? Как бы вы легко отобразили похожий вывод с помощью короткой команды?
om01

6
@ om01: на osx это сложно brew install tree, учитывая, что вы используете homebrew
ccpizza

я не могу перечислить файлы исключительно. в нем также всегда перечислены каталоги. Как я могу это сделать?
kommradHomer

Это должно быть оценено намного выше!
der_grund

44

О, действительно длинный список ответов. Это очень помогло и, наконец, я создал свой собственный, который я искал:

Чтобы вывести список всех файлов в каталоге и его подкаталогах:

find "$PWD" -type f

Чтобы вывести список всех каталогов в каталоге и его подкаталогах:

find "$PWD" -type d

Чтобы вывести список всех каталогов и файлов в каталоге и его подкаталогах:

find "$PWD"

2
И отфильтровать по расширению:find "$PWD" -type f | grep '\.json$'
Killroy

2
Нет необходимости пост-обработки с помощью grep, используйте -name в find, например: find "$ PWD" -type f -name * .json и, если вы хотите удалить перечисленные файлы: find "$ PWD" -type f -name * .json -exec rm {} \; аналогично, если вы хотите скопировать его, замените rm на cp и destination: -exec cp {} destination
Godfather

18

Я не знаю о полном пути, но вы можете использовать -Rдля рекурсии. Кроме того, если вы не склонны ls, вы можете просто сделать find *.


16

Не используя никаких внешних команд, кроме ls:

ls -R1 /path | 
  while read l; do case $l in *:) d=${l%:};; "") d=;; *) echo "$d/$l";; esac; done


Неизвестная опция '-1'. Aborting.
САО

15
du -a

Удобно для некоторых ограниченных оболочек устройства, где поиск / локализация недоступны.


1
Любая идея, как я могу удалить размер файла без awk?
Арнольд Роа


10

Не усложняй. Я просто использовал это и получил красивый вывод:

ls -lR /path/I/need

3
ОП хочет только полный путь и больше ничего. ls -lRне достиг бы этой цели.
codeforester

извините, он этого не делает
Арье Бейтц

9

Самый простой способ для всех вас, будущих людей, это просто:

du

Это, однако, также показывает размер содержимого каждой папки. Вы можете использовать awk для вывода только имени папки:

du | awk '{print $2}'

Edit- Извините, мой плохой. Я думал, что это были только папки, которые были необходимы. Я оставлю это здесь на всякий случай, если кому-то понадобится в будущем ...


Интересно, потому что он показывает мне то, что я не знал, что хотел знать - вроде как Google предлагает. Оказывается, мне нравится знать, сколько места занимает каждый файл.
Джейк Торонто


9

Я думаю, что для плоского списка лучший способ:

find -D tree /fullpath/to-dir/ 

(или для того, чтобы сохранить его в текстовом файле)

find -D tree /fullpath/to-dir/ > file.txt

3
Пробовал на Mac OS 10.13.3. find: illegal option -- D
Джаянт Бхавал


6

Вот частичный ответ, который показывает имена каталогов.

ls -mR * | sed -n 's/://p'

Объяснение:

ls -mR * перечисляет полные имена каталогов, заканчивающиеся на ':', затем перечисляет файлы в этом каталоге отдельно

sed -n 's/://p' находит строки, оканчивающиеся на двоеточие, снимает двоеточие и печатает строку

Перебирая список каталогов, мы также сможем найти каталоги. Все еще работаю над этим. Получать подстановочные знаки через xargs сложно.


отличный ответ .. именно то, что мне нужно!
Селвин

5

Добавление подстановочного знака в конец каталога ls приводит к полному пути. Прямо сейчас у вас есть это:

$ ls /home/dreftymac/
foo.txt
bar.txt
stackoverflow
stackoverflow/alpha.txt
stackoverflow/bravo.txt
stackoverflow/charlie.txt

Вы можете сделать это вместо этого:

$ ls /home/dreftymac/*
/home/dreftymac/.
/home/dreftymac/foo.txt
/home/dreftymac/bar.txt
/home/dreftymac/stackoverflow:
alpha.txt
bravo.txt
charlie.txt

К сожалению, это не выводит полный путь к каталогам, в которые возвращаются, поэтому, возможно, это не то полное решение, которое вы ищете.


Также, к сожалению, вы не можете использовать подстановочный знак (потому что подстановочный знак раскрывается как обычный пользователь).
Эндрю Лориен

4

Я вижу много ответов. Это мое, и я считаю весьма полезным, если вы работаете на Mac.

Я уверен, что вы знаете, что есть несколько « пакетных » файлов ( .app , .rtfd , .workflow и т. Д.). И глядя в окно Finder, они кажутся отдельными файлами. Но это не так. И $ lsили $ findрассматривать их как каталоги ... Итак, если вам не нужно перечислять их содержимое, это работает для меня:

find . -not -name ".*" -not -name "." | egrep -v "\.rtfd/|\.app/|\.lpdf/|\.workflow/"

Конечно, это для рабочего каталога, и вы можете добавить расширения других пакетов (но всегда с /последующим после них). Или любые другие расширения, если не пакет без /.

Скорее интересное " .lpdf/" (многоязычный pdf). У него нормальное " .pdf" расширение (!!) или нет в Finder. Таким образом, вы получите (или он просто считает 1 файл) за это, pdfа не кучу вещей ...


4

ls -lR это то, что вы искали, или, по крайней мере, я был. ура


ОП хочет только полный путь и больше ничего. ls -lRне достиг бы этой цели.
Адриен Тома

3

Если каталог передается как относительный путь, и вам нужно преобразовать его в абсолютный путь перед вызовом find. В следующем примере каталог передается в качестве первого параметра в сценарий:

#!/bin/bash

# get absolute path
directory=`cd $1; pwd`
# print out list of files and directories
find $directory

Если у вас есть система, readlinkвы можете сделать этоdirectory=$(readlink -e $1)
Пауза до дальнейшего уведомления.

Правда, но комбинация cd / pwd будет работать на любой системе. readlinkна OS X 10.5.8 не поддерживает опцию -e.
Джон Киз

3
tar cf - $PWD|tar tvf -             

Это медленно, но работает рекурсивно и печатает как каталоги, так и файлы. Вы можете передать его с помощью awk / grep, если вам нужны имена файлов без всей остальной информации / каталогов:

tar cf - $PWD|tar tvf -|awk '{print $6}'|grep -v "/$"          

2
Вы также можете просто использовать: tar cvf / dev / null $ PWD
RuleB

2

@ ghostdog74: немного подправить свое решение.
Следующий код может быть использован для поиска файла с полным абсолютным путем.

sudo ls -R / | awk '<br/>
/:$/&&f{s=$0;f=0}<br/>
/:$/&&!f{sub(/:$/,"");s=$0;f=1;next}<br/>
NF&&f{ print s"/"$0 }' | grep [file_to_search]

1

Я знал имя файла, но также хотел каталог.

найти $ PWD | имя файла

отлично работал в Mac OS 10.12.1

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.