Remover caminho da saída do comando find

22

Eu tenho um script bash para a implantação de código de um ambiente beta para um ambiente de produção, mas atualmente eu tenho que adicionar a lista de arquivos para um arquivo txt manaully e às vezes eu sinto falta de alguns. Basicamente, meu script de implantação cat / loops copia os arquivos. (exporta / importa também db mas isso não é relevante..lol)

De qualquer forma, gostaria de usar o comando find para gerar uma lista de arquivos modificados nos últimos 14 dias. O problema é que eu preciso remover o caminho ./ para que o script de implantação funcione.

Veja um exemplo do uso do comando find:

find . -type f -mtime -14 > deploy.txt

Aqui está a linha que gatos deploy.txt no meu script de implantação:

for i in 'cat deploy.txt'; do cp -i /home/user/beta/public_html/$i /home/user/public_html/$i; done

Alguma ideia de como fazer isso usando o script do bash?

Obrigado!

    
por Mikey1980 27.01.2012 / 21:59

8 respostas

27

Você pode usar a opção de linha de comando -printf com %f para imprimir apenas o nome do arquivo sem nenhuma informação de diretório

find . -type f -mtime -14 -printf '%f\n' > deploy.txt

ou você pode usar sed para remover apenas o arquivo ./

find . -type f -mtime -14 | sed 's|^./||' >deploy.txt
    
por 23.02.2018 / 20:00
9

O ./ deve ser inofensivo. A maioria dos programas tratará /foo/bar e /foo/./bar como equivalentes. Eu percebo que não parece muito legal, mas com base no que você postou, não vejo razão para que o script falhe.

Se você realmente quer despir, sed é provavelmente a maneira mais limpa:

find . -type d -mtime 14 | sed -e 's,^\./,,' > deploy.txt

Se você está em um sistema com o GNU find (por exemplo, na maioria dos sistemas Linux), você pode fazer isso em uma única chance com find -printf :

find . -type d -mtime 14 -printf "%P\n" > deploy.txt

O %P retorna o caminho completo de cada arquivo encontrado, menos o caminho especificado na linha de comando, até e incluindo a primeira barra. Isso preservará todos os subdiretórios da sua estrutura de diretórios.

    
por 27.01.2012 / 22:36
6

Por que você precisa retirar o ./ ? É válido ter um caminho. Então

cp -i dir1/./somefile dir2/./somefile

é apenas ok!

Mas se você quiser remover o nome do diretório encontrado, é possível usar o %P arg para -printf .

man encontrar (1) diz:

         %P     File's name with the name of the  command  line  argument
                 under which it was found removed.

Um exemplo

$ find other -maxdepth 1
other
other/CVS
other/bin
other/lib
other/doc
other/gdbinit
$ find other -maxdepth 1 -printf "%P\n"

CVS
bin
lib
doc
gdbinit

Cuide da primeira linha vazia! Se você quiser evitar, use -mindepth 1

$ find other -mindepth 1 -maxdepth 1 -printf "%P\n"
CVS
bin
lib
doc
gdbinit
    
por 29.05.2013 / 12:01
3

Bem, você tem algumas opções. Você poderia usar a opção -printf em find para imprimir apenas o nome do arquivo, ou você poderia usar uma ferramenta como sed para simplesmente remover o ./ .

# simply print out the filename, will break if you have sub-directories.
find . -mtime -14 -printf '%f\n'

# strip a leading ./
find .  -mtime -14 | sed -e 's/^\.\///'
    
por 27.01.2012 / 22:06
3
A solução "find -printf" não funcionará no FreeBSD porque o find não tem essa opção. Neste caso, o AWK pode ajudar. Ele retorna um sobrenome ($ NF), então ele pode trabalhar em qualquer profundidade.

find /usr/local/etc/rc.d -type f | awk -F/ '{print $NF}'

PS: tirado de D.Tansley "Livro de programação em shell Linux e Unix"

    
por 26.05.2014 / 18:12
2

Uma solução rápida, se eu entendi corretamente a pergunta, está usando cut na saída do comando find :

$> find . -type f -mtime -14 | cut -b 3- > deploy.txt

Isso tira o primeiro dos caracteres de cada linha do resultado (no seu caso, ./ ). Provavelmente não é a melhor solução, mas funciona no seu cenário.

    
por 27.01.2012 / 22:12
1

sed é perfeito para esse tipo de coisa.

$ find . -type f -mtime -14 find . | sed 's/^\.\///' > deploy.txt
    
por 27.01.2012 / 22:08
1

Eu não sei de que tipo de nomes de arquivo estamos falando, mas qualquer coisa com espaços ou novas linhas coloca a maioria das soluções aqui em risco.

Minha sugestão seria usar a expansão de parâmetros do shell para remover os caracteres de cada nome de arquivo:

find . -mtime -14 -exec sh -c 'printf "${0#./}\n"' {} \; >deploy.txt

Se você realmente gostar de pipes, pode usar um delimitador "seguro", como um nulo, com xargs para receber cada nome de arquivo:

find . -mtime -14 -print0 | xargs -0 -n 1 sh -c 'printf "${0#./}\n"' >deploy.txt

Lembre-se de que a saída disso não é delimitada por nulos, de modo que, embora possa ser suficiente para uma verificação visual, nenhuma dessas soluções produz um arquivo deploy.txt seguro para uso na automação , a menos que você esteja muito confiante sobre seus nomes de fontes.

    
por 21.02.2017 / 18:59