web-dev-qa-db-fra.com

Dans un script bash, comment passer d'un entier variable à une commande 'sed -e' (18.04)

J'essaie de créer un script bash qui supprime les fichiers les plus anciens d'un répertoire avec une variable définissant la quantité de fichiers à conserver.

Ma première étape a été de compter le nombre de fichiers antérieurs à un nombre défini de 10 fichiers les plus récents à conserver:

#!/bin/bash
# How many files in the current directory are older than the retained files
olderThanRetain=$(find -maxdepth 1 -type f | sort -r | sed -e '1,10d' | wc -l)
echo $olderThanRetain

Fonctionne bien.

Mais quand j'essaie de définir une variable pour le nombre de fichiers à conserver:

#!/bin/bash
retain=10
# How many files in the current directory are older than the retained files
olderThanRetain=$(find -maxdepth 1 -type f | sort -r | sed -e "1,(( $retain ))d" | wc -l)
echo $olderThanRetain

Mais cela me donne l'erreur:

sed: -e expression #1, char 3: unexpected `,'

Qu'est-ce que j'ai manqué?

1
Broadsworde

Comme la virgule n’est pas un caractère spécial dans bash il n’est pas nécessaire de citer cette expression, vous pouvez simplement utiliser:

_sed 1,${retain}d
_

Pour éviter les problèmes liés aux noms de fichiers étranges (imaginez un nom de fichier avec une nouvelle ligne), utilisez _0_ comme séparateur de ligne. De plus, je ne suis pas tout à fait sûr de ce que vous triez ici, pour trier en sens inverse par la dernière heure d’accès que je ferais:

_find -maxdepth 1 -type f -printf "%A@ %p\0" | sort -zr | sed -z 's/[^ ]* //;'1,${retain}d
_

Vous pouvez modifier _0_ en nouvelle ligne avec _tr \\0 \\n_. Pour compter les lignes délimitées par des zéros, vous pouvez utiliser _tr -cd '\0' | wc -c_, voir Compter les éléments nuls délimités dans le fichier · U & L .

Des explications

  • _find -maxdepth 1 -type f -printf "%A@ %p\0"_ - recherche tous les fichiers (_-type f_) dans le répertoire en cours sans recherche de sous-répertoires (_-maxdepth 1_) et affiche _"%A@ %p\0"_ (sans nouvelle ligne!).
    _%A@_ est remplacé par le temps d'accès du fichier en secondes depuis l'époque , _%p_ par le nom du fichier et _\0_ par le caractère nul , voir _man find_/EXPRESSION/ACTIONS/-printf pour obtenir la liste complète des échappements et des directives.
  • _sort -zr_ - trier z données délimitées par des zéros dans r ordre inverse
  • _sed -z 'a;b_ - exécute les expressions sed a et b sur chaque entrée avec zero comme délimiteur d'entrée
    Il vous suffit de citer des caractères spéciaux pour le shell, voir mon post sur la citation ici . En fait, dans ce cas, la seule chose que vous devez citer est _;_ (en utilisant des guillemets ou entre guillemets simples ou doubles), donc _sed -z s/[^ ]* //\;1,${retain}d_ convient également.
    • _s/[^ ]* //_ - ssubstitute la première chaîne ne contenant pas le caractère espace (= tout jusqu'au dernier caractère espace) et le caractère espace qui la suit sans rien (= le supprime)
    • _1,${retain}d_ - supprime les premières _$retain_ entrées
1
dessert