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?


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-

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 .)

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'

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 {} \;

Legal - obrigado por me mostrar --relative-to.
nneonneo 1/01
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.