Saída "find" relativa ao diretório

34

Eu gostaria de usar findpara listar todos os arquivos e diretórios recursivamente em uma determinada raiz para uma cpiooperação. No entanto, não quero que o diretório raiz apareça nos caminhos. Por exemplo, atualmente recebo:

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

Mas eu gostaria de obter

file1
dir1
dir1/file2

(observe que a raiz também não está na saída desejada, mas é fácil livrar-se disso tail).

Estou no OS X e prefiro não instalar nenhuma ferramenta extra (por exemplo, GNU find), se possível, pois gostaria de compartilhar o script que estou escrevendo com outros usuários do OS X.

Estou ciente de que isso pode ser feito cutpara reduzir a listagem de raiz, mas isso parece uma solução abaixo do ideal. Existe uma solução melhor disponível?

nneonneo
fonte
find diskimg/* | cut -d '/' -f2-
Nik.shornikov

Respostas:

18

Se o que você está tentando fazer não for muito complexo, você poderá fazer isso com o sed:

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

Ou cut:

find diskimg | cut -sd / -f 2-
BriGuy
fonte
você pode escolher (quase) qualquer separador para o comando, então: find diskimg | grep -v '^diskimg$' | sed -e 's|^diskimg/||'(observe que eu adicionei também '-e' e uma ^prática recomendada (não é necessária aqui, pois você tem certeza de que todas as linhas terão isso ... mas ainda é uma prática recomendada) e economiza um pouco de CPU;))
Olivier Dulac
de outra maneira sem grep: find diskimg | sed -e 's|^diskimg/*||' (o '/ *' corresponderá a qualquer número de '/', até 0)
Olivier Dulac
Este cutcomando é mais limpo que o que eu usei; Eu gosto disso. (A sedsolução também é boa, mas a repetição de diskimg/é um pouco infeliz).
N12:
29

cd no diretório primeiro:

cd diskimg && find . 

Após a conclusão, você estará de volta ao seu diretório raiz.

Seus arquivos serão anexados com ./ neste caso; a única maneira que vejo ao redor disso seria usando cut:

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

Use um subshell para evitar alterar o diretório atual do seu shell (isso não é necessário se você estiver canalizando a saída porque o lado esquerdo de um pipe já roda em um subshell).

(cd diskimg && find .)
Stephan
fonte
5
por estar de volta no diretório original na conclusão: adicionar parêntese: (cd diskimg && find . ; ). Dessa forma, isso cd diskimg && find .é feito em um subshell: quando esse subshell sai, você volta ao seu próprio shell, em qualquer diretório em que estava.
Olivier Dulac
11
find *é outra maneira de contornar o prefixo inútil
nik.shornikov
23

Outro, mais complexo, mas apenas usando a abordagem find da minha outra resposta:

find diskimg -mindepth 1 -printf '%P\n'
Stephan
fonte
Nem todas as versões do findsuporte printf.
Jordanm
11
Certamente; Meu OSX não, ao que parece. Em parte porque eu ofereci outra solução.
Stephan
2
@Stephan - da próxima vez, você pode apenas combinar esses tipos de respostas em uma única. Não é necessário fazer várias respostas para variações como essa.
slm
2
Somente o GNU findsuporta -printf, embora muitos BSDs findtenham copiado alguns dos recursos do GNU find, nenhum -printfainda foi copiado (AFAIK).
Stéphane Chazelas
o %Pcaminho relativo era o que eu precisava.
Fl0v0 5/03
4

Use o realpathutilitário:

find diskimg -exec realpath --relative-to diskimg {} \;
dwjbosman
fonte
Legal - obrigado por me mostrar --relative-to.
nneonneo 1/01