«Найти» вывод относительно каталога

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чтобы отключить корневой список, но это кажется неоптимальным решением. Есть ли лучшее решение?

nneonneo
источник
find diskimg/* | cut -d '/' -f2-
Ник.шорников

Ответы:

18

Если то, что вы пытаетесь сделать, не слишком сложно, вы можете сделать это с помощью sed:

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

Или cut:

find diskimg | cut -sd / -f 2-
BriGuy
источник
Вы можете выбрать (почти) любой разделитель для команды, поэтому: find diskimg | grep -v '^diskimg$' | sed -e 's|^diskimg/||'(обратите внимание, я добавил также '-e' и такую ^же хорошую практику (здесь нет необходимости, так как вы уверены, что в каждой строке будет это ... но все же хорошая практика) и сохраняет немного процессора;))
Оливье Дюлак
иначе без grep: 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 .)
Stephan
источник
5
чтобы быть в оригинальной директории на достройку: добавить скобки: (cd diskimg && find . ; ). Таким образом, cd diskimg && find .это делается в подоболочке: когда эта подсолла выходит, вы возвращаетесь в свою собственную оболочку, в какой бы директории вы ни находились.
Оливье Дюлак
1
find *это еще один способ обойти бесполезный префикс
nik.shornikov
23

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

find diskimg -mindepth 1 -printf '%P\n'
Stephan
источник
Не все версии findподдержки printf.
Иордания
1
Конечно, Мой OSX, кажется, нет. Отчасти поэтому я предложил другое решение.
Стефан
2
@Stephan - в следующий раз вы можете просто объединить эти типы ответов в один. Нет необходимости делать несколько ответов для таких отклонений, как этот.
SLM
2
findПоддерживает только GNU -printf, в то время как многие BSD findскопировали некоторые функции GNU find, еще ни одна не скопировала -printf(AFAIK).
Стефан Шазелас
%Pдля относительного пути было то , что мне нужно.
Fl0v0
4

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

find diskimg -exec realpath --relative-to diskimg {} \;
dwjbosman
источник
Опрятно - спасибо, что показали мне --relative-to.
nneonneo