déplacer des fichiers plus anciens qu’un jour

J’utilise le script ci-dessous pour déplacer les fichiers plus anciens qu’un jour vers un autre répertoire, et je vérifiais simplement avec une déclaration d’ echo si cela fonctionnait correctement.

  for i in `ls -lhrt | grep TRACK` do for j in `$i | awk '{print $7}'` do if [[ $j -lt $((`date | awk '{print $3}'` - 1)) ]]; then echo $j less than $((`date | awk '{print $3}'` - 1)) fi done done 

Mais je vois quelques erreurs et le script ne fonctionne pas correctement. Si je fais un ls -lhrt | grep TRACK | awk '{print $7}' ls -lhrt | grep TRACK | awk '{print $7}' ls -lhrt | grep TRACK | awk '{print $7}' , cela fonctionne bien et renvoie la date (le champ numérique).

Si je modifie le script comme:

  for i in `ls -lhrt | grep TRACK | awk '{print $7}'` do if [[ $i -lt $((`date | awk '{print $3}'` - 1)) ]]; then echo $i less than $((`date | awk '{print $3}'` - 1)) fi done 

Cela fonctionne bien si.

Quelle est la logique exacte que je manque dans le script original?

Votre script fonctionne en supposant que le premier pour la boucle ( for i in ... ) effectue une itération sur les lignes, mais cette hypothèse est fausse. Si vous ajoutez un echo "$i" dans le corps de la boucle, vous verrez qu’il opère sur des mots, pas sur des lignes.

La prochaine erreur a déjà été signalée et est-ce que dans la ligne

 for j in `$i | awk '{print $7}'` 

le script essaie d’exécuter le contenu de la variable $ i. Vous voulez append une commande echo ici, comme ceci:

 for j in `echo $i ... 

Mais bien sûr, cela ne résoudrait pas votre problème, car $ i contient déjà des mots simples et il n’y aura pas de 7ème mot que awk pourrait imprimer.

Une solution simple (si vous insistez pour ne pas utiliser find ) est en effet ce que vous avez déjà écrit:

 for i in `ls -lhrt | grep TRACK | awk '{print $7}'` 

Mais si vous souhaitez conserver les deux boucles, vous pouvez modifier la variable spéciale IFS (séparateur de champs interne) dans le script, comme ceci:

 #!/bin/bash OIFS="$IFS" IFS=" " for i in `ls -lhrt` ; do IFS="$OIFS" echo ">>$i<<" for j in `echo $i|awk '{print $7}'` ; do echo ">>$j<<" done done 

La ligne avec IFS=" ne contient rien après " l'atsortingbution se termine à la ligne suivante avec le simple " et affecte donc le caractère de saut de ligne à la variable spéciale IFS. Veillez à restaurer IFS dès que possible dans vos scripts. vous ne parvenez pas à le faire, vous obtiendrez un comportement très déroutant de la part du shell, car les espaces ne séparent plus les mots ...)

PS: Vous savez que votre script échouera chaque fois qu'un nouveau mois commence?

PPS: Vous savez que votre script dépend des parameters régionaux actuels? Sur mon PC, le 7ème mot des lignes est "Dez" à cette époque de l’année, alors j’ai dû append un LANG=C lors de l’exécution du script.

Juste vu votre mise à jour

 $i | ... 

va essayer d’exécuter un exécutable appelé quelle que soit la valeur de $i . Dans votre cas, cela fonctionnera pour $ i = 1, 2 et 3 (mais ne faites pas ce que vous voulez) et échouera autrement.

Vous souhaitez envoyer la chaîne au processus suivant dans le tube, ne pas exécuter un exécutable sous ce nom. Tu as besoin de faire

 echo $i | ...