Как я могу создать список файлов с их абсолютным путем в Linux?


304

Я пишу сценарий оболочки, который принимает пути к файлам в качестве входных данных.

По этой причине мне нужно генерировать рекурсивные списки файлов с полными путями. Например, файл barимеет путь:

/home/ken/foo/bar

но, насколько я вижу, оба lsи findтолько дают списки относительного пути:

./foo/bar   (from the folder ken)

Это кажется очевидным требованием, но я не вижу ничего на страницах findили lsman.

Как я могу создать список файлов в оболочке, включая их абсолютные пути?


Используйте:find /home/ken/foo/bar -exec ls -ld $PWD/{} \;
Учащийся

Ответы:


305

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

find "$(pwd)" -name .htaccess

или если ваша оболочка расширяется $PWDдо текущего каталога:

find "$PWD" -name .htaccess

find просто добавляет путь, который был указан для относительного пути к файлу из этого пути.

Грег Хьюгилл также предложил использовать, pwd -Pесли вы хотите разрешить символические ссылки в вашем текущем каталоге.


9
Обратите внимание, что если вы также хотите разрешить символические ссылки, используйте pwd -P.
Грег Хьюгилл

5
Это полезно, но я думаю, что ответ user431529 ниже более действителен: ls -d -1 $PWD/**/*но я думаю, что find $PWDтакже работает (протестировано в bash)
Brian

9
@ Брайан, почему? find $PWDпросто. lsКолдовство является сложным и громоздким (если вы не псевдонимом его). findне зависит от расширений глобуса оболочки, поэтому будет работать в любой оболочке. findКроме того, он гораздо более гибкий, я могу получить рекурсивный список всех файлов, или, возможно, всех каталогов, или, может быть, я хочу получить список всех файлов XML или всех файлов, измененных за последнюю неделю. Все, что возможно с find, но не легко с ls.
Мэтью Шарли

12
Мне пришлось использовать find "`pwd`" -name .htaccessиз-за пробелов в именах каталогов
Paulo Casaretto

Я не понимаю, эта команда не дает мне абсолютный путь к файлу I, в то время как другие ответы внизу списка делают свою работу.
Бьёрн Отто Васботтен

202
readlink -f filename 

дает полный абсолютный путь. но если файл является символической ссылкой, вы получите окончательное разрешенное имя.


8
Ницца. Не работает на BSD Variant readlink (т.е. Mac). Я использую gnucoreutils на Mac. И, следовательно, может использовать greadlink, который работает с вышеуказанным решением.
Шеки

12
Не ходите на Mac OS X.
Эндрю Лазарь

1
@AndrewLazarus - для Mac OS X используйте realpathвместо этого
cz

если вы установите Баш инструменты с помощью brew install coreutils, то исполняемый файл будет установлен как/usr/local/opt/coreutils/libexec/gnubin/readlink
благоухающая

121

Используйте это для dirs ( в bash необходимо использовать /after, **чтобы ограничить его каталогами):

ls -d -1 "$PWD/"**/

это для файлов и каталогов непосредственно в текущем каталоге, чьи имена содержат .:

ls -d -1 "$PWD/"*.*

это для всего:

ls -d -1 "$PWD/"**/*

Взято отсюда http://www.zsh.org/mla/users/2002/msg00033.html

В bash **рекурсивно, если вы включаете shopt -s globstar.


1
ls -d -1 $ PWD / ** / * не повторяется. Хотел бы я забрать +1 назад. Вы можете сделать ** для каждой глубины, которую вам нужно пройти, хотя.
user606723

4
Оператор ** является оператором рекурсивного смещения. Если вы используете команду в оболочке, которая ее поддерживает (например, zsh), она будет работать правильно.
zebediah49

ls -d1 "$ PWD /"ndom*,.*}, чтобы также перехватывать скрытые (точечные) файлы. Для меня рекурсивная версия в ответе не предшествует абсолютному пути к файлам в подпапках.
Заэль

Я думаю, мне придется использовать find ... Я получаю -> bash: / bin / ls: Список аргументов слишком длинный
TelamonAegisthus

30

Ты можешь использовать

find $PWD 

в баш


3
Это даст путь к текущему каталогу, а также все файлы и каталоги под ним. Это, вероятно, не то, что люди ищут.
Билл

18
ls -d "$PWD/"*

Это выглядит только в текущем каталоге. Он заключает в кавычки "$ PWD", если он содержит пробелы.


Это все еще очень правильный ответ, но было бы хорошо включить информацию о том, что это не работает рекурсивно (именно это я и искал на самом деле!)
bbbco

1
Для рекурсивного использования: найти. -exec ls -ld $ PWD / {} \;
Учащийся

10

Команда: ls -1 -d "$PWD/"*

Это даст абсолютные пути к файлу, как показано ниже.

[root@kubenode1 ssl]# ls -1 -d "$PWD/"*
/etc/kubernetes/folder/file-test-config.txt
/etc/kubernetes/folder/file-test.txt
/etc/kubernetes/folder/file-client.txt

8

Это $PWDхороший вариант Мэтью выше. Если вы хотите найти только для печати файлов, вы также можете добавить опцию -type f для поиска только обычных файлов. Другие параметры - "d" только для каталогов и т. Д. Так что в вашем случае это будет (если я хочу искать только файлы с .c ext):

find $PWD -type f -name "*.c" 

или если вы хотите все файлы:

find $PWD -type f

Примечание: Вы не можете сделать псевдоним для вышеуказанной команды, потому что $ PWD автоматически заполняется к вашему домашнему каталогу, когда псевдоним устанавливается bash.


На самом деле -d означает не только каталоги, но и каталоги как файлы. Так что если вы ls -d / home, вы вернетесь "/ home", а не список того, что находится в / home.
Трэвис

@Travis: он говорил о возможности найти, а не о ls. В его случае «find / -type d» найдет только каталоги - как он сказал.
oligofren

6

Если вы дадите команде find абсолютный путь, она выдаст результаты с абсолютным путем. Итак, из каталога Кена, если вы наберете:

find /home/ken/foo/ -name bar -print    

(вместо относительного пути find . -name bar -print)

Вы должны получить:

/home/ken/foo/bar

Поэтому, если вы хотите, чтобы ls -lи он возвращал абсолютный путь, вы можете просто сказать команде find выполнить ls -lвсе, что он находит.

find /home/ken/foo -name bar -exec ls -l {} ;\ 

ПРИМЕЧАНИЕ. Между {}и;

Вы получите что-то вроде этого:

-rw-r--r--   1 ken admin       181 Jan 27 15:49 /home/ken/foo/bar

Если вы не уверены, где находится файл, вы всегда можете изменить место поиска. Пока путь поиска начинается с «/», вы получите в ответ абсолютный путь. Если вы ищете место (например, /), в котором вы получите много ошибок об отказе в разрешении, я бы порекомендовал перенаправить стандартную ошибку, чтобы вы могли увидеть результаты поиска:

find / -name bar -exec ls -l {} ;\ 2> /dev/null

( 2>это синтаксис для оболочек Borne и Bash, но он не будет работать с оболочкой C. Она может работать и в других оболочках, но я точно знаю, что она работает в Bourne и Bash).


Вы можете передать несколько аргументов в один и тот же lsпроцесс с помощью -exec ls -ld {} +. (Возможно, вы не хотите -dиметь lsсписок содержимого каталога). Или лучше, используйте встроенный поиск lsс find ... name bar -ls. Кроме того, у вас неправильный синтаксис для одного аргумента в команде: вам нужно заключить точку с запятой в оболочку, так что это так {} \;.
Питер Кордес

5

fd

Используя fd(альтернатива find), используйте следующий синтаксис:

fd . foo -a

Где .находится шаблон поиска и fooявляется корневым каталогом.

Например , чтобы получить список всех файлов в etcрекурсивно, выполните: fd . /etc -a.

-a, --absolute-path Показать абсолютные вместо относительных путей


3

Просто альтернатива

ls -d "$PWD/"* 

точно определить, что *расширение оболочки, так

echo "$PWD/"*

будет делать то же самое (недостаток, который вы не можете использовать -1для разделения новыми строками, а не пробелами).


не могли бы вы подробнее рассказать об этом? что такое расширение оболочки? как использовать -1для разделения по строкам?
Антонио Араужо

@Antonio Araujo, расширение оболочки - оболочка (например, bash) заменит * списком файлов - подробнее об этом можно узнать на man-странице bash. -1 - опция команды ls, echo - другая команда, она не имеет таких же опций.
Мариша


1

Вот пример, который выводит список без дополнительного периода, а также демонстрирует, как искать совпадение файла. Надеюсь это поможет:

find . -type f -name "extr*" -exec echo `pwd`/{} \; | sed "s|\./||"

1

Это сработало для меня. Но это не перечислить в алфавитном порядке.

find "$(pwd)" -maxdepth 1

Эта команда перечисляет в алфавитном порядке, а также список скрытых файлов.

ls -d -1 "$PWD/".*; ls -d -1 "$PWD/"*;


1

Вы можете попробовать это.

for name in /home/ken/foo/bar/*
do
    echo $name
done

Вы можете получить путь пресса с помощью forцикла и echoпросто без find.


0

Если вам нужен список всех файлов в текущем, а также подкаталогах

find $PWD -type f

Если вам нужен список всех файлов только в текущем каталоге

find $PWD -maxdepth 1 -type f

0

Это даст канонический путь (разрешит символические ссылки): realpath FILENAME

Если вы хотите канонический путь к самой символической ссылке, то: realpath -s FILENAME


0

Большинство, если не все из предложенных методов приводят к путям, которые нельзя использовать непосредственно в какой-либо другой терминальной команде, если путь содержит пробелы. В идеале результаты будут иметь косые черты. Это работает для меня на MacOS:

find / -iname "*SEARCH TERM spaces are okay*" -print 2>&1  | grep -v denied |grep -v permitted |sed -E 's/\ /\\ /g'

-1

find / -print сделаю это


1
... к сожалению, он будет делать что-то еще (например, отображать «некоторые» другие файлы, если они не отфильтрованы)
DerMike

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