AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 569541
Accepted
SebMa
SebMa
Asked: 2020-02-25 21:40:39 +0800 CST2020-02-25 21:40:39 +0800 CST 2020-02-25 21:40:39 +0800 CST

find não consegue excluir um diretório específico

  • 772

Eu quero listar todos os arquivos, exceto aqueles dentro .git/do diretório findapenas com o comando.

Eu tentei isso:

$ find . -path .git -prune -type f
$

ele retornou 0 arquivos (em vez dos 2 que eu tenho), então eu tentei isso:

$  find . -not -path .git -type f | grep -c '\.git'
1770
$

Eu não entendo porque nada disso está funcionando, você pode ajudar?

EDIT0 : Graças a @icarus, vejo que os caminhos devem ser precedidos ./e que estava faltando o ORoperador consequentemente, este comando funciona:

$ find . -path ./.git -prune -o -type f | grep '\.git'
./.git
./.gitignore
$

EDIT1: Por que esse outro comando não funciona?

$ find . -not -path ./.git -a -type f | grep -c '\.git'
1770
$

EDIT2: Uma última pergunta: por que o -prunepredicado precisa de um -o -printpara não imprimir o ./.gite ./.gitignoreresulta no comando abaixo:

$ find . -name ".git*" -prune | grep git
./.git
./.gitignore
$ find . -name ".git*" -prune -o -print | grep -c git
0

EDIT3: Obrigado @rastafile:

$ find . -name ".git*" -prune | grep git
./.git
./.gitignore
$ find . -name ".git*" -prune -print | grep git
./.git
./.gitignore
$ find . -name ".git*" -prune -o -print | grep git
$

Parece que o GNU encontra -prunechamadas de predicado -printimplicitamente quando a expressão anterior é verdadeira:

Se a expressão não contiver outras ações além de -prune, -print será executado em todos os arquivos para os quais a expressão for verdadeira.

Em conclusão: O comando que eu preciso é:

$ find . -name ".git*" -prune -o -type f -print

Obrigado a todos.

find
  • 2 2 respostas
  • 236 Views

2 respostas

  • Voted
  1. icarus
    2020-02-25T22:09:57+08:002020-02-25T22:09:57+08:00

    A operação padrão para juntar termos em find é andtão

    find / -user root -name fred
    

    significa encontrar arquivos que pertencem ao root e são chamados de fred. Você quer fazer uma oroperação, se ela for chamada de ".git" então podá-la ou se for um arquivo então listá-lo.

    find . \( -name .git -prune \) -o -type f
    

    Observe que estou usando -nameem vez de -path. Se você fornecer um local inicial de ., o .gitdiretório no nível superior será chamado ./.gitpara fins de -path.

    Então

    find . -path .git -prune -type f
    

    não dá nada porque nada corresponde -path .gità medida que todos os arquivos são iniciados./

    find . -not -path .git -type f
    

    fornece todos os arquivos porque tudo corresponde -not -path .git, portanto, a única filtragem é -type frestringir a saída aos arquivos.

    • 2
  2. Best Answer
    user373503
    2020-02-26T13:11:10+08:002020-02-26T13:11:10+08:00

    Há uma grande diferença entre -pathe -name-- eles não são nada parecidos: "name" só olha para a última parte, "path" para toda a cadeia de barras. O que um "nome de arquivo" deve significar, ou um "nome de caminho", é sempre um pouco controverso. Mas aqui é claro e importante.

    Isso funciona (você diz):

    find . -path ./.git -prune -o -type f 
    

    Você começa com ., então o gitdir padrão é encontrado e removido. Nenhum outro ./.gitexiste, então todos os outros ( -o) são verificados quanto ao tipo de arquivo.


    Seu último exemplo:

    find . -not -path ./.git -a -type f 
    

    não funciona, apenas encontra todos os arquivos .

    Se você deseja evitar -prune, deve corresponder a cada entrada dentro:

    -path './.git/*'
    

    Concordo com a combinação -name/-prune de Icarus, mas tenho uma modificação:

    ]# find . -name .git -prune -o -type f -name '*git*' -print   
    ./.git.filehidd
    ./gitfile
    

    Os parênteses não são necessários, aqui.

    Mesmo que -name '*git*'seja adicionado, para testar/reduzir a saída.

    A ação explícita -printno final suprime uma impressão por poda:

    ]# find . -name .git -prune                                 
    ./.git
    ./10/.git
    

    Eu não tinha certeza sobre os pais; Eu procurei man find(GNU) e encontrei este bom detalhe sobre eles:

     find . -name .snapshot -prune -o \( \! -name *~ -print0 \)
    

    ..., mas omite arquivos e diretórios chamados .snapshot (e qualquer coisa neles). Ele também omite arquivos ou diretórios cujo nome termina em ~, mas não seu conteúdo. A construção -prune -o \( ... -print0 \) é bastante comum. A ideia aqui é que a expressão antes de -prune corresponda às coisas que devem ser podadas. No entanto, a ação -prune em si retorna true, então o seguinte -o garante que o lado direito seja avaliado apenas para os diretórios que não foram removidos (o conteúdo dos diretórios removidos nem sequer é visitado, portanto, seu conteúdo é irrelevante ). A expressão no lado direito do -o está entre parênteses apenas para maior clareza. Ele enfatiza que a ação -print0 ocorre apenas para coisas que não tiveram -prune aplicado a elas. Como a condição padrão 'e' entre os testes é mais forte do que -o , esse é o padrão de qualquer maneira, mas os parênteses ajudam a mostrar o que está acontecendo.

    Para mim, a clareza seria reforçada por:

    find . ( -name .snapshot -prune ) -o ( ! -name '*~' -print0 )
    

    Mas assim não funciona!

    E se você deixar o -alike aqui, o -odestaque se destaca o suficiente, então os parênteses podem ser deixados de fora, também para maior clareza.


    (Como o shell também gosta de parênteses, você precisa citá-los . Mas adeus à clareza.)

    1) find . -name .snapshot -prune -o \( \! -name *~ -print0 \)
    
    2) find . -name .snapshot -prune -o ! -name '*~' -print0 
    

    O sem aspas !pode funcionar (o meu funciona), o sem aspas *não.


    Então, para encontrar arquivos (todos os tipos), exceto em qualquer diretório .git:

    find -name '.git' -type d -prune -o -print 
    

    (o tipo -d também pode ser deixado de fora, se você não se importar ... veja o comentário de Kamil ... é uma selva lá fora , e find é uma pequena linguagem de programação : o que você precisa)

    • 1

relate perguntas

  • Comportamento estranho para localizar se o padrão seguinte -name não estiver entre aspas

  • Imprima variáveis ​​do subshell para o shell pai [duplicado]

  • verificando se existe uma pasta em determinado diretório

  • Localizar e substituir cores em arquivos CSS na linha de comando

  • GNU find: obtenha caminho absoluto e relativo em -exec

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve