Bash : changer la date de modification de fichiers avec find et file

Bonjour,

Je m’arrache les cheveux à trouver une commande élégante pour rechercher avec find des vieux fichiers doc et xls ayant une date de modification erronée (31/12/1997) et remplacer celle-ci par la date conservée dans les propriétés lues par file.

J’arrive pour l’instant à trouver les fichiers, afficher leur date de modification erronée et à afficher leurs propriétés :
find . \( -name *.doc -o -name *.xls \) -newermt 1997-12-30 ! -newermt 1998-01-01 -printf %p\|%T+\| -exec file -b {} \;

Ça me renvoie par exemple :
./chemin/vers/fichier.doc|1997-12-31+21:19:56.0000000000|Composite Document File V2 Document, Little Endian, Os: Windows, Version 4.10, Code page: 1252, Title: xxx , Author: xxx, Template: Normal.dot, Last Saved By: xxx, Revision Number: 4, Name of Creating Application: Microsoft Word 8.0, Total Editing Time: 05:00, Create Time/Date: Wed Feb 6 13:33:00 2002, Last Saved Time/Date: Wed Feb 6 15:06:00 2002, Number of Pages: 1, Number of Words: 1366, Number of Characters: 7788, Security: 0

Dans un premier temps j’aimerais juste filtrer la sortie de file avec seulement la valeur de Last Saved Time/Date mais je n’arrive pas à faire suivre file d’un tube avec par exemple sed ou awk.

Comment faire ?

Merci

LSam

salut,

find ... -exec sh -c 'file "$1" | awk ...' sh {} \;

mais, l’imbrication des quotes simples et doubles, va rendre l’écriture et l’exécution difficiles.
il serait peut-être plus simple de faire un petit script qui serait appeler avec l’-exec

Bonjour

En supposant que le même nombre de champs soient retournés, il suffirait de faire :

 find . \( -name *.doc -o -name *.xls \) -newermt 1997-12-30 ! -newermt 1998-01-01 -printf %p\|%T+\| -exec file -b {} \; | awk -F',' '{print $14}'

=======
Sinon, il y a beaucoup mieux à faire avec awk que ce que j’ai fait,
et il y a aussi bash :

maRe='Last Saved Time/Date: (.*), Number of Pages: '
[[ $(find . \( -name *.doc -o -name *.xls \) -newermt 1997-12-30 ! -newermt 1998-01-01 -printf %p\|%T+\| -exec file -b {} \;)  =~ $maReg ]]
echo ${BASH_REMATCH[1]}
Wed Feb 6 15:06:00 2002
1 J'aime

Bonjour,

Merci à tous les 2 !

Ça fonctionne très bien avec :

find . \( -name *.doc -o -name *.xls \) -newermt 1997-12-30 ! -newermt 1998-01-01 -printf %p\|%T+\| -exec sh -c 'file -b "$1" | sed "s/\, /\n/g" | grep "Last Saved Time"' sh {} \;

Pour ma culture perso, $1 remplace {} lorsqu’on exécutesh -c dans -exec ?
C’est le sh {} à la fin qui a été décisif dans la réussite, je ne comprend pas trop son rôle.

Quant à la dernière proposition de MicP, pourrais-tu m’expliquer ${BASH_REMATCH[1]}. Sinon la commande ne fonctionne pas, car elle ne renvoie la date que du 1er fichier trouvé puis toutes les propriétés lues par file concaténées à la suite.

Bonjour

Pas trop en forme, j’avais pris le retour texte que tu avais transmis dans ton premier message,
et je me suis arrangé pour en extraire la date/heure.
(D’un autre côté, je n’ai pas de fichiers .doc ni .xls pour faire des tests)

Du coup, j’avais complètement oublié qu’il y en aurait une liste entière…:confused:


Pour le BASH_REMATCH c’est ce qui est entre parenthèses dans la Regex qui est gardé <=> Entre les deux motifs.

Entre :

man bash

et tape un caractère / suivit de 5 espaces et de BASH_REMATCH puis tape sur la touche entrée :

/     BASH_REMATCH

En suivant le conseil de watael tu pourrais créer un script monScript.sh contenant :

#!/bin/bash

dateStat="$(date --date="$(stat --printf=%y "${1}")")"
dateFile="$(date --date="$(file --brief "${1}" | awk -F',' '{print $14}')")"

echo -e "\nNom du fichier\t\t\t: ${1}"
echo -e "Données meta\t\t\t: ${dateFile}"
echo -e "Dernière modification d’état\t: ${dateStat}"

# Lignes suivantes à décommenter si besoin
#dateTouch=$(date '+%Y%m%d%H%M.%S' --date="${dateFile}")
#touch -t $dateTouch "${1}"

Le script monScript.sh serait appelé par la ligne de commande find :

find . \( -name *.doc -o -name *.xls \) -newermt 1997-12-30 ! -newermt 1998-01-01 -exec monScript.sh {} \;