web-dev-qa-db-fra.com

Comment puis-je supprimer un fichier s'il commence par <html> dans bash?

J'ai besoin d'une commande bash pour supprimer le fichier entier si celui-ci commence par <html>.

Je ne suis pas sûr de la meilleure façon de s'y prendre ...

Contexte: Je télécharge une série de fichiers via des requêtes curl. La plupart du temps, les téléchargements et le traitement fonctionnent correctement. Mais d’autres fois, la demande de téléchargement génère un 404 pour une raison quelconque. Lorsque je les reçois, le contenu du fichier téléchargé commence par une balise html. Lorsque le reste de mon traitement touche ce fichier, il se bloque. Donc, je veux exécuter une commande avant mon autre traitement pour lire chacun des fichiers et supprimer le fichier s'il contient cette balise html.

7
BeMy Friend

Pour répondre à la question qui vous a incité à poser celle-ci, plutôt que celle que vous avez réellement posée:

curl peut vous indiquer le code d’état en plus du téléchargement du fichier. Vous n'avez pas besoin de vérifier le contenu du fichier pour cela. Voici un exemple de vérification de l'état

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

Les différentes options que vous pouvez utiliser avec -w sont décrites dans le manuel. Selon vos besoins, vous pouvez étendre cela à la sortie de plus d’informations et les analyser, et/ou changer la vérification du code d’état pour permettre plus que 200.

20
hvd

Vous pouvez utiliser cette commande find pour supprimer tous les fichiers ne contenant que le motif <html> dans la première ligne:

find . -type f -exec sh -c 'sed q "$0" | grep -qP "^<html>$" && rm "$0"' {} \;
12
Sylvain Pineau

Je viens de tester ça, ça marche.

Lancez shopt en premier car nous ne voulons pas analyser ls :

shopt -s nullglob  

puis utilisez une simple boucle for bash pour rechercher les fichiers commençant par <html> et les supprimer:

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

Il serait plus sûr d'utiliser:

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

pour que rm demande avant de supprimer des fichiers, juste au cas où.

Notez que shopt n'est pas strictement nécessaire, mais évite certains problèmes si le répertoire est vide ou s'il existe un fichier avec un astérisque dans son nom.

8
Seth

Toutes les tâches d'automatisation ne doivent pas nécessairement être effectuées avec Shell. Voici un script 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()

Peut-être que c'est plus bavard que les commandes équivalentes de bash, mais c'est

  1. Plus lisible
  2. Plus extensible
  3. Ne vous fiez jamais à des noms de fichiers avec des espaces et des métacaractères Shell, aussi négligents que vous soyez.
1
Siyuan Ren