Вихід "знайти" щодо каталогу


34

Я хотів би використати findдля того, щоб перелічити всі файли та каталоги рекурсивно в заданому корені для cpioоперації. Однак я не хочу, щоб сам кореневий каталог з’являвся у шляхах. Наприклад, зараз я отримую:

$ find diskimg
diskimg
diskimg/file1
diskimg/dir1
diskimg/dir1/file2

Але я хотів би отримати

file1
dir1
dir1/file2

(зауважте, корінь також не в моєму бажаному виході, але це легко позбутися tail).

Я перебуваю на OS X, і я вважаю за краще не встановлювати додаткових інструментів (наприклад, GNU find), якщо це можливо, оскільки я хотів би поділитися сценарієм, про який пишу, з іншими користувачами OS X.

Я знаю, що це можна зробити, cutщоб відрізати кореневий список, але це здається субоптимальним рішенням. Чи є краще рішення?


find diskimg/* | cut -d '/' -f2-
nik.shornikov

Відповіді:


18

Якщо те, що ви намагаєтеся зробити, не надто складне, ви можете зробити це за допомогою sed:

find diskimg | sed -n 's|^diskimg/||p'

Або cut:

find diskimg | cut -sd / -f 2-

ви можете вибрати (майже) будь-який роздільник для команди, так що: find diskimg | grep -v '^diskimg$' | sed -e 's|^diskimg/||'(зауважте, я додав також "-e", і ^як хороша практика (тут не потрібно, оскільки ви впевнені, що в кожному рядку буде таке ... але все-таки хороша практика) , і економить трохи процесора;))
Олів'є Дулак

інший спосіб без грепу: find diskimg | sed -e 's|^diskimg/*||' ("/ *" відповідатиме будь-якій кількості "/", навіть 0)
Олів'є Дулак

Ця cutкоманда чистіша за ту, яку я використав; Мені це подобається. ( sedРішення теж приємне, але повторення diskimg/трохи прикро).
nneonneo

29

cd спочатку в каталог:

cd diskimg && find . 

По завершенні ви повернетесь у свій кореневий каталог.

У цьому випадку ваші файли будуть попередньо використані ./; Єдиний спосіб, який я бачу навколо, це буде використовувати cut:

{ cd diskimg && find .; } | tail -n +2 | cut -c 3-

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

(cd diskimg && find .)

5
щоб бути в оригінальній директорії на добудову: додати дужки: (cd diskimg && find . ; ). Таким чином, cd diskimg && find .це робиться в підзаголовці: коли ця нижня оболонка виходить, ви повертаєтесь до своєї власної оболонки, в якій би каталог ви не були.
Олів'є Дулак

1
find *ще один спосіб обійти непотрібну приставку
nik.shornikov

23

Ще одна, більш складна, але лише з використанням підходу пошуку з моєї іншої відповіді:

find diskimg -mindepth 1 -printf '%P\n'

Не всі версії findпідтримки printf.
jordanm

1
Безумовно; Моя ОСX, здається. Частково тому я запропонував інше рішення.
Стефан

2
@Stephan - наступного разу ви зможете просто поєднати ці типи відповідей в одну. Не потрібно складати кілька відповідей на такі відхилення.
slm

2
Тільки findпідтримує GNU -printf, хоча багато BSD findкопіювали деякі функції GNU find, жодна з них -printfще не скопіювала (AFAIK).
Стефан Шазелас

%Pдля відносного шляху було те , що мені потрібно.
Fl0v0

4

Використовуйте realpathутиліту:

find diskimg -exec realpath --relative-to diskimg {} \;

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