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 / 766132
Accepted
FxMySz
FxMySz
Asked: 2024-01-05 02:26:59 +0800 CST2024-01-05 02:26:59 +0800 CST 2024-01-05 02:26:59 +0800 CST

Como listar recursivamente todos os arquivos cujo conteúdo inteiro é exatamente “\n”

  • 772

Tenho alguns arquivos de resultados de experimentos com falha e seu conteúdo é exatamente um único \n(nova linha).

Gostaria de listá-los todos (talvez com algo como findou grep), para saber quais são os arquivos e depois excluí-los.

bash
  • 6 6 respostas
  • 1342 Views

6 respostas

  • Voted
  1. Best Answer
    Kamil Maciorowski
    2024-01-05T03:03:34+08:002024-01-05T03:03:34+08:00

    Crie um arquivo de referência fora do caminho de pesquisa (estará .no exemplo):

    echo >/tmp/reference
    

    Agora temos um arquivo conhecido idêntico ao que você está procurando. Em seguida, compare todos os arquivos regulares no caminho de pesquisa ( .aqui) com o arquivo de referência:

    find . -type f -size 1c -exec cmp -s -- /tmp/reference {} \; -print
    

    -size 1cnão é necessário, pode ser omitido; é apenas para melhorar o desempenho. É um teste preliminar rápido que rejeita arquivos de tamanhos errados, sem gerar processos adicionais. Processos relativamente caros cmp …serão criados apenas para arquivos do tamanho certo.

    -sfica cmpem silêncio . Não precisamos de sua saída, apenas do status de saída.

    --é explicado aqui: O que significa "--" (traço duplo)? Na verdade, não é necessário em nosso caso de exemplo, ou seja, se o arquivo de referência for especificado como /tmp/referencee o caminho de pesquisa for .. Usei-o --no caso de alguém escolher descuidadamente caminhos que, de outra forma, fariam com que cmpse comportasse mal ou fracassassem; com --isso deve funcionar.

    -execé usado como um teste, será bem-sucedido se e somente se cmpretornar o status de saída zero; e para um arquivo testado isso acontecerá se o arquivo for idêntico a /tmp/reference. Dessa forma, findvocê receberá os nomes dos caminhos dos arquivos idênticos ao arquivo de referência.

    O método pode ser usado para localizar arquivos com qualquer conteúdo fixo; você só precisa de um arquivo de referência com o conteúdo exato (e não se esqueça de ajustar -size …se for usá-lo; -size "$(</tmp/reference wc -c)c"será útil). No nosso caso específico echofoi usado um simples para criar o arquivo porque ele imprime um caractere de nova linha, que é exatamente o conteúdo que você deseja encontrar.

    Para findtentar excluir cada arquivo correspondente, use -delete(xor -exec rm -- {} +) depois -print.

    • 29
  2. Chris Davies
    2024-01-05T02:54:56+08:002024-01-05T02:54:56+08:00

    Procure arquivos com um único byte. Compare-os com o valor conhecido. Imprima e/ou exclua se corresponder

    find /path/to/files -type f -size 1c -exec sh -c 'printf "\n" | cmp -s -- - "$1"' _  {} \; -print
    

    Opcionalmente, anexe -deletepara excluir e remova -printse desejar uma execução silenciosa.

    • 8
  3. terdon
    2024-01-06T21:10:24+08:002024-01-06T21:10:24+08:00

    Com GNU grep, você pode -ztratar o arquivo inteiro como uma única linha ( -zfaz grepuso de NUL como o terminador de linha, portanto, desde que seus arquivos não contenham NUL, \0ele tem o efeito de tratar o arquivo inteiro como um único linha). Se combinarmos isso com -lapenas imprimir o nome do arquivo e -Pusar os PCREs \n, podemos procurar por "linhas" que tenham apenas uma \ne nada mais:

    grep -lPz '^\n$' *
    

    Por exemplo, dados estes três arquivos:

    printf 'foo\n' > good_file_1
    printf '\n\n\n\n' > good_file_2
    printf '\n' > bad_file
    

    Executar o grepacima dá:

    $ grep -lPz '^\n$' *
    bad_file
    

    Você também pode torná-lo recursivo, usando a globstaropção bash (de man bash):

    estrela glob

    Se definido, o padrão ** usado em um contexto de expansão de nome de caminho corresponderá a todos os arquivos e a zero ou mais diretórios e subdiretórios. Se o padrão for seguido por /, apenas diretórios e subdiretórios corresponderão.

    Então, por exemplo, nesta situação:

    $ mkdir -p ./some/long/path/here/
    $ cp bad_file some/long/path/here/bad_file_2
    $ tree
    .
    ├── bad_file
    ├── good_file_1
    ├── good_file_2
    └── some
        └── long
            └── path
                └── here
                    └── bad_file_2
    
    5 directories, 4 files
    

    Ativar globstare executar grepencontrará **/*ambos os arquivos inválidos (estou redirecionando o erro padrão porque o grep reclama de receber diretórios para pesquisar em vez de arquivos; tais erros são esperados e podem ser ignorados com segurança):

    $ grep -lPz '^\n$' **/* 2>/dev/null 
    bad_file
    some/long/path/here/bad_file_2
    

    Como alternativa, use findpara pesquisar apenas arquivos:

    $ find . -type f -exec grep -lPz '^\n$' {} +
    ./some/long/path/here/bad_file_2
    ./bad_file
    
    • 5
  4. Stéphane Chazelas
    2024-01-05T17:24:17+08:002024-01-05T17:24:17+08:00

    Com zsh:

    zmodload zsh/mapfile
    print -rC1 -- **/*(ND.L1e[$' [[ $mapfile[$REPLY] = "\n" ]] '])
    
    • print -rC1: printvi rno 1 Column
    • N: nullglob: não reclame se não houver correspondência e, printem vez disso, passe uma lista vazia para.
    • D: dotglob: não pule arquivos ocultos
    • .: apenas arquivos regulares (como -type fin findou file/ fin rawhide).
    • L1: de Linglês 1.
    • e[code]executa o código no arquivo para determinar se é uma correspondência
    • $mapfile[$REPLY]expande para o conteúdo do arquivo (cujo caminho está em $REPLY).

    POSIXly, e evitando gerar um ou mais processos por arquivo (assumindo uma shimplementação where read, [and printfare builtin, o que geralmente é o caso):

    find . -type f -size 1c -exec sh -c '
      for file do
        IFS= read -r line < "$file" && [ -z "$line" ] && printf "%s\n" "$file"
      done' sh {} +
    

    (observe que, ao contrário do zsh acima, a lista não está classificada).

    Com rawhide(lista também não classificada):

    rh -e 'file && size == 1 && "
    ".body' .
    

    Com grepimplementações que podem lidar com arquivos não-texto (pelo menos bytes NUL e linhas não delimitadas), como GNU grepna localidade C, você também pode fazer:

    LC_ALL=C find . -type f -size 1c -exec grep -l '^$' {} +
    
    • 3
  5. glenn jackman
    2024-01-05T02:55:42+08:002024-01-05T02:55:42+08:00
    find . -size 1c -exec sh -c '[ -z "$(< $1)" ]' sh '{}' ';' -print
    

    Procura arquivos com tamanho de exatamente um byte, onde o resultado da leitura do arquivo (em um shell) está vazio - sh remove as novas linhas das substituições de comandos.

    • 2
  6. Jim L.
    2024-01-05T03:29:22+08:002024-01-05T03:29:22+08:00

    Apenas para apresentar uma nova alternativa, no FreeBSD, isso poderia ser feito como:

    find . -maxdepth 1 -size 1c \
      -exec md5 -q '--check=68b329da9893e34099c7d8ad5cb9c940 {} >/dev/null' \; -print 
    

    No entanto, um hash md5, mesmo de um arquivo pequeno, é provavelmente um pouco mais caro do que um simples arquivo cmp.

    Tentei encontrar uma maneira de formular o cmpmétodo usando basha substituição de comando (e BSD find), mas é um pouco desajeitado:

    find . -maxdepth 1 -size 1c -exec bash -c 'cmp -s "{}" <(echo)' \; -print
    

    Novamente, provavelmente um pouco mais caro criar o arquivo de nova linha várias vezes do que o método Kamil de criar o arquivo de referência uma vez e compará-lo repetidamente.

    • 1

relate perguntas

  • exportar variáveis ​​​​env programaticamente, via stdout do comando [duplicado]

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

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