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


304

Я пишу сценарій оболонки, який приймає шляхи до файлу як вхідні дані.

З цієї причини мені потрібно генерувати рекурсивні списки файлів із повними шляхами. Наприклад, файл barмає шлях:

/home/ken/foo/bar

але, наскільки я бачу, обидва lsі findлише дають відносні списки шляхів:

./foo/bar   (from the folder ken)

Це здається очевидною вимогою, але я нічого не бачу на сторінках man 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
Це корисно, але я думаю, що відповідь користувача431529 нижче є більш вірною: ls -d -1 $PWD/**/*але, мабуть, find $PWDтакож працює (тестується в баші)
Брайан

9
@Brian Чому? find $PWDпросто. lsЧаклунство є складним і громіздким (якщо ви не псевдонімом його). findне залежить від глобальних розширень оболонок, тому буде працювати в будь-якій оболонці. findтакож набагато гнучкіше, я можу отримати рекурсивний перелік усіх файлів або, можливо, всіх каталогів, або, можливо, я хочу перелічити всі XML-файли, або всі файли змінені за останній тиждень. Все, що можна find, але не легко ls.
Меттью Шарлі

12
Мені довелося використовувати find "`pwd`" -name .htaccessчерез пробіли в назвах каталогів
Paulo Casaretto

Я не розумію, ця команда не дає мені абсолютного шляху файлу, який я, а інші відповіді в списку виконує цю роботу.
Bjørn Otto Vasbotten

202
readlink -f filename 

дає повний абсолютний шлях. але якщо файл є символьним посиланням, ви отримаєте остаточне вирішене ім'я.


8
Приємно. Не працює на BSD Варіанті readlink (тобто Mac). Я використовую gnucoreutils на mac. А значить, можна скористатися перехідною посиланням, яке працює з вищезазначеним рішенням.
sheki

12
Не переходьте на Mac OS X.
Андрій Лазар

1
@AndrewLazarus - Для Mac OS X використовуйте realpathнатомість
cz

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

121

Використовуйте це для dirs ( /після **цього потрібно в bash, щоб обмежити його каталогами):

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

це для файлів і каталогів безпосередньо в поточному каталозі, імена якого містять .:

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

це для всього:

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

Взято звідси http://www.zsh.org/mla/users/2002/msg00033.html

**Якщо увімкнути баш, є рекурсивним shopt -s globstar.


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

4
Оператор ** - рекурсивний глобальний оператор. Якщо ви використовуєте команду в оболонці, яка її підтримує (наприклад, zsh), вона буде працювати належним чином.
zebediah49

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

Я думаю, що мені доведеться скористатися знаходженням ... я отримую -> 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" знайшов би лише каталоги - як він сказав.
олігофрен

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>це синтаксис оболонок Борна і Баша, але він не працюватиме з оболонкою С. Він може працювати і в інших оболонках, але я точно знаю, що він працює в Борні і Баші).


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

5

fd

Використовуючи fd(альтернативно find), використовуйте наступний синтаксис:

fd . foo -a

Де .шаблон пошуку та fooкореневий каталог.

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

-a, --absolute-path Показати абсолютний замість відносних шляхів


2

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

ls -d "$PWD/"* 

точно визначити, що *це розширення оболонки, так

echo "$PWD/"*

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


Ви можете детальніше розглянути це? що таке розширення оболонки? як використовувати -1для розділення ліній?
Антоніо Арауджо

@Antonio Araujo, розширення оболонки оболонки (наприклад, bash) замінить * зі списком файлів - можна прочитати більше на сторінці bash man. -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

stat

Абсолютний шлях одного файлу:

stat -c %n "$PWD"/foo/bar

1

Ви можете спробувати це.

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

Ви можете отримати abs шлях, використовуючи 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.