Como posso deletar um arquivo se ele começar com html no bash?

7

Eu preciso de um comando bash para excluir o arquivo inteiro se o próprio arquivo começar com <html> .

Eu não tenho certeza qual é a melhor maneira de fazer isso ...

Contexto: faço o download de uma série de arquivos por meio de solicitações de curl. Na maioria das vezes, os downloads e o processamento funcionam bem. Mas outras vezes o pedido de download resulta em um 404 por qualquer motivo. Quando eu os obtenho, o conteúdo do arquivo baixado começa com uma tag html. Quando o restante do meu processamento atinge esse arquivo, ele trava. Então eu quero executar um comando antes do meu outro processamento para catar cada um dos arquivos e excluir o arquivo se ele tiver essa tag html.

    
por BeMy Friend 28.10.2014 / 05:15

4 respostas

20

Para resolver a questão que levou você a fazer essa pergunta, em vez da pergunta que você fez:

O

curl pode informar o código de status, além de fazer o download do arquivo. Você não precisa verificar o conteúdo do arquivo para isso. Um exemplo de como verificar o status é

status=$(curl -w '%{http_code}' "${url}" -o "${file}")
test "${status}" -eq 200 || rm -- "${file}"

As várias opções que você pode usar com -w estão documentadas no manual e, dependendo de suas necessidades, você pode querer estender isso para gerar mais informações e analisá-las e / ou alterar a verificação do código de status para permitir mais do que apenas 200.

    
por hvd 28.10.2014 / 13:32
12

Você pode usar este comando find para excluir todos os arquivos contendo apenas o padrão <html> na primeira linha:

find . -type f -exec sh -c 'sed q "$0" | grep -qP "^<html>$" && rm "$0"' {} \;
    
por Sylvain Pineau 28.10.2014 / 08:35
8

Acabei de testar isso, funciona.

Execute shopt primeiro porque não queremos analisar ls :

shopt -s nullglob  

use então um loop simples bash for para encontrar arquivos que começam com <html> e os remova:

for i in *; do if [ "$(head -n 1 "$i")" == '<html>' ]; then rm "$i"; fi; done  

Seria mais seguro usar:

for i in *; do if [ "$(head -n 1 "$i")" == '<html>' ]; then rm -i "$i"; fi; done  

para ter rm perguntado antes de remover qualquer arquivo, apenas no caso.

Observe que shopt não é estritamente necessário, mas evita a ocorrência de certos problemas se o diretório estiver vazio ou se houver um arquivo com um asterisco em seu nome.

    
por Seth 28.10.2014 / 05:21
1

Nem toda tarefa de automação deve ser feita com o shell. Aqui está um script em Python

#!/usr/bin/env python
import os

def is_html_file(file_name):
    # Actually, try/except is better
    # But not very readable for someone not familiar with python
    if not os.path.isfile(file_name):
        return False
    with open(file_name, 'rb') as f:
        # A lot of HTML file starts with doctype
        # It is better to check that too
        return f.read(6) == '<html>'

def main():
    # Use os.walk if recursion is needed
    for fn in os.listdir('.'):
        if is_html_file(fn):
            print 'Removing', fn, '...'
            os.remove(fn)

main()

Talvez seja mais detalhado do que os comandos bash equivalentes, mas é

  1. Mais legível
  2. Mais extensível
  3. Nunca será estragado por nomes de arquivos com espaços e metacaracteres de shell, por mais descuidado que você seja.
por Siyuan Ren 01.11.2014 / 17:07