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

**URL:** <https://www.debian-fr.org/t/bash-changer-la-date-de-modification-de-fichiers-avec-find-et-file/70895>\
**Category:** Programmation\
**Created:** [Septembre 10, 2016, 2:14 UTC](https://www.debian-fr.org/t/bash-changer-la-date-de-modification-de-fichiers-avec-find-et-file/70895 "2016-09-10T14:14:01Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![lsam](https://www.debian-fr.org/user_avatar/www.debian-fr.org/lsam/32/12965_2.png) [@lsam](https://www.debian-fr.org/u/lsam)\
**Post date:** [Septembre 10, 2016, 2:14 UTC](https://www.debian-fr.org/t/bash-changer-la-date-de-modification-de-fichiers-avec-find-et-file/70895/1 "2016-09-10T14:14:01Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Watael](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/w/a4c791/32.png) [@Watael](https://www.debian-fr.org/u/Watael)\
**Post date:** [Septembre 10, 2016, 3:20 UTC](https://www.debian-fr.org/t/bash-changer-la-date-de-modification-de-fichiers-avec-find-et-file/70895/2 "2016-09-10T15:20:07Z")

</div>

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_

---

<div class="post-metadata">

**Author:** ![anon29980398](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/f4b2a3/32.png) [@anon29980398](https://www.debian-fr.org/u/anon29980398)\
**Post date:** [Septembre 10, 2016, 3:58 UTC](https://www.debian-fr.org/t/bash-changer-la-date-de-modification-de-fichiers-avec-find-et-file/70895/3 "2016-09-10T15:58:33Z")

</div>

Bonjour

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

```auto
 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 :

```auto
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

```

---

<div class="post-metadata">

**Author:** ![lsam](https://www.debian-fr.org/user_avatar/www.debian-fr.org/lsam/32/12965_2.png) [@lsam](https://www.debian-fr.org/u/lsam)\
**Post date:** [Septembre 11, 2016, 3:24 UTC](https://www.debian-fr.org/t/bash-changer-la-date-de-modification-de-fichiers-avec-find-et-file/70895/4 "2016-09-11T15:24:14Z")

</div>

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écute`sh -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.

---

<div class="post-metadata">

**Author:** ![anon29980398](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/f4b2a3/32.png) [@anon29980398](https://www.debian-fr.org/u/anon29980398)\
**Post date:** [Septembre 11, 2016, 4:25 UTC](https://www.debian-fr.org/t/bash-changer-la-date-de-modification-de-fichiers-avec-find-et-file/70895/5 "2016-09-11T16:25:59Z")

</div>

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…😕

* * *

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

Entre :

```bash
man bash

```

et tape un caractère **/** suivit de 5 espaces et de **BASH\_REMATCH** puis tape sur la touche entrée :

```auto
/ BASH_REMATCH

```

* * *

En suivant le conseil de **watael** tu pourrais créer un script **[monScript.sh](http://monScript.sh)** contenant :

```bash
#!/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](http://monScript.sh)** serait appelé par la ligne de commande find :

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

```
