# Parser les espaces du nom d'un fichier (sortie de find + sed + array)

**URL:** <https://www.debian-fr.org/t/parser-les-espaces-du-nom-dun-fichier-sortie-de-find-sed-array/90442>\
**Category:** Programmation\
**Tags:** bash\
**Created:** [Octobre 16, 2024, 4:33 UTC](https://www.debian-fr.org/t/parser-les-espaces-du-nom-dun-fichier-sortie-de-find-sed-array/90442 "2024-10-16T04:33:02Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![anon36725218](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/8e8cbc/32.png) [@anon36725218](https://www.debian-fr.org/u/anon36725218)\
**Post date:** [Octobre 16, 2024, 4:33 UTC](https://www.debian-fr.org/t/parser-les-espaces-du-nom-dun-fichier-sortie-de-find-sed-array/90442/1 "2024-10-16T04:33:02Z")

</div>

Bonjour,

J’essaie de récupérer une liste des fichiers modifiés (depuis X min) dans un répertoire.

Exemple (je vous laisse les options de la commande `find` pour information personnelle :

```auto
find "/home/USER/" ! -path "/home/USER/ignore/*" -type f \( -iname "*" -or -iname ".*" ! -iname ".afileignore" \) -mmin -60 -exec ls -lh {} \; | awk '{print $9":"$5}')

```

Qui me ressort :

```auto
/home/USER/my_file.txt:85K
/home/USER/my_file_second.txt:195K

```

Par contre **si j’ai un fichier qui contient des espaces çà bug**.

Exemple : «&nbsp;`/home/USER/my_file_avec espace.txt`&nbsp;» ; ma commande `find` ne fonctionne pas , elle me retourne :

```auto
/home/USER/my_file_avec

```

Qui a une solution ?

> _Je souhaite garder la taille des fichiers._

Merci.

Bonne journée.

Romain.

* * *

Note de Moi-même :

> **TEST**
>
> ```auto
> root@lb2.ww2:~ $ find /var/pro/web_public/ -mmin -1200 -exec ls -lh {} \;
> total 679M
> -rw-r--r-- 1 1000 1000 17K Feb 5 2024 "Capture d'écran 2024-02-05 195622.png"
> 
> ```
> 
> ```auto
> root@lb2.ww2:~ $ find /var/pro/web_public/ -mmin -1200 -exec ls -lh {} \; | sed -f /root/url_escape.sed
> total%20679M
> -rw-r--r--%201%201000%201000%20%20%2017K%20Feb%20%205%20%202024%20Capture%20d'écran%202024-02-05%20195622.png
> 
> ```
> 
> le fichier : «&nbsp;`cat url_escape.sed`&nbsp;» : [CF](https://stackoverflow.com/questions/296536/how-to-urlencode-data-for-curl-command).
> 
> ```auto
> # sed url escaping
> s:%:%25:g
> s: :%20:g
> s:<:%3C:g
> s:>:%3E:g
> s:#:%23:g
> s:{:%7B:g
> s:}:%7D:g
> s:|:%7C:g
> s:\\:%5C:g
> s:\^:%5E:g
> s:~:%7E:g
> s:\[:%5B:g
> s:\]:%5D:g
> s:`:%60:g
> s:;:%3B:g
> s:/:%2F:g
> s:?:%3F:g
> s^:^%3A^g
> s:@:%40:g
> s:=:%3D:g
> s:&:%26:g
> s:\$:%24:g
> s:\!:%21:g
> s:\*:%2A:g
> 
> ```
> 
> C’n’est pas encore çà. Je cherche..

---

<div class="post-metadata">

**Author:** ![anon36725218](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/8e8cbc/32.png) [@anon36725218](https://www.debian-fr.org/u/anon36725218)\
**Post date:** [Octobre 16, 2024, 7:55 UTC](https://www.debian-fr.org/t/parser-les-espaces-du-nom-dun-fichier-sortie-de-find-sed-array/90442/2 "2024-10-16T07:55:32Z")

</div>

Je crois bien que j’ai réussis :

```auto
root@lb2.ww2:~ # ls -lhQ
total 264K
-rw-r--r-- 1 root root 17K Oct 16 08:16 "Capture d'écran 2024-02-05 195622.png"
-rw-r--r-- 1 root root 46K Oct 16 08:16 "Capture d'écran 2024-02-05 195739.png"
-rw-r--r-- 1 root root 40K Oct 16 08:16 "Capture d'écran 2024-02-05 200425.png"
-rw-r--r-- 1 root root 21K Oct 16 08:16 "Capture d'écran 2024-02-05 235747.png"
-rw-r--r-- 1 root root 33K Oct 16 08:16 "Capture d'écran 2024-02-05 235843.png"

```

Je cherche le 9ème champ «&nbsp;le titre&nbsp;» et le 5ème champ le «&nbsp;poid&nbsp;» 😉

```auto
find . -maxdepth 1 -name "*.png" -exec ls -lhQ {} ';' | sed -r 's/(.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]]"([^"]+)"$/\9:\5/g'

```

OK çà me retourne les noms entier des fichiers et j’ajoute le poid :

```auto
./Capture d'écran 2024-02-05 195622.png:17K
./Capture d'écran 2024-02-05 195739.png:46K
./Capture d'écran 2024-02-05 235843.png:33K
./Capture d'écran 2024-02-05 235747.png:21K
./Capture d'écran 2024-02-05 200425.png:40K

```

J’ai ajouté l’option (`-Q`,` --quote-name` enclose entry names in double quotes) de la commande `ls`

Puis j’ai parsé tout les champs entre les espaces.  
Puis je vérifie dès que je tombe sur une double quote, je récupère tous les caractères tant que ce n’est pas une double quote `"([^"]+)"` et dollar de fin de ligne.

Si vous avez de meilleur solution, je suis preneur.

😉

* * *

J’ai un autre problème ; c’est sur mon «&nbsp;array&nbsp;» bash. je n’arrive pas à le créer, qui a une soluce ? merci !

```auto
root@lb2.ww2:~ $ search=$(find /root/ -type f -name "*.png" -mmin -600 -exec ls -lhQ {} ';' |sed -r 's/(.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]]"([^"]+)"$/"\9:\5"/g') ; \
echo ""; \
IFS=""; array=(${search}) ; \
count=$(echo ${#array[@]}); \
echo "$count dans array"; \
for file in "${array[@]}"; do echo "-> $file"; done;

```

Me retourne :

```auto

1 dans array
-> "/root/Capture d'écran 2024-02-05 195622.png:17K"
"/root/Capture d'écran 2024-02-05 195739.png:46K"
"/root/Capture d'écran 2024-02-05 235843.png:33K"
"/root/Capture d'écran 2024-02-05 235747.png:21K"
"/root/Capture d'écran 2024-02-05 200425.png:40K"
root@lb2.ww2:~ #

```

j’ai essayé d’ajouter un retour ligne, ou nouvelle ligne et une tabulation à la sortie de la commande «&nbsp;sed&nbsp;» mais çà ne fonctionne pas non plus.

```auto
sed -r '/XXX/"\9:\5\r"/g'

```

😕

---

<div class="post-metadata">

**Author:** ![vbreton](https://www.debian-fr.org/user_avatar/www.debian-fr.org/vbreton/32/11400_2.png) [@vbreton](https://www.debian-fr.org/u/vbreton)\
**Post date:** [Octobre 16, 2024, 9:46 UTC](https://www.debian-fr.org/t/parser-les-espaces-du-nom-dun-fichier-sortie-de-find-sed-array/90442/3 "2024-10-16T09:46:43Z")

</div>

Bonjour @anon36725218,

Il aurait été préférable de séparer votre réponse de votre nouveau besoin par un nouveau message.

Pour répondre à votre problème, je vous invite dans un premier temps à remplacer `array=(${search})` par `array=("fichier1.txt" "fichier2.txt" "fichier3.txt")`pour faire la part des choses.  
Vous identifierez ainsi la ligne à la source du problème. Il y a fort à parier que ce soit la première.

Dans un deuxième temps remplacez, «&nbsp;file1.txt&nbsp;» par «&nbsp;/root/Capture d’écran 2024-02-05 195622.png:17K&nbsp;»

Progressivement vous identifierez de façon de plus en plus précise l’origine du ou des problèmes rencontrés.

---

<div class="post-metadata">

**Author:** ![anon36725218](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/8e8cbc/32.png) [@anon36725218](https://www.debian-fr.org/u/anon36725218)\
**Post date:** [Octobre 16, 2024, 10:27 UTC](https://www.debian-fr.org/t/parser-les-espaces-du-nom-dun-fichier-sortie-de-find-sed-array/90442/4 "2024-10-16T10:27:41Z")

</div>

Bonjour, et merci pour la réponse @vbreton monsieur. En créant le tableau à la main çà fonctionne l’array.

C’est la sortie du «&nbsp;`find`&nbsp;» ; le «&nbsp;`sed`&nbsp;» qui met «&nbsp;tout sur une ligne&nbsp;» (pourtant il y a bien des espaces entre chaque «&nbsp;fichier&nbsp;» entre double-quotes et/ou des sauts de lignes.

On dirait que «&nbsp;sed&nbsp;» ne veut pas créait de tableau.

J’ai trouvé tout va bien …  
J’ai entouré la déclaration du tableau array= **"** (${search}) **"**  
Et j’ai envoyé **declare -a** pour déclarer le tableau proprement.

```auto
# search=$(find /root/ -type f -name "*.png" -mmin -600 -exec ls -lhQ {} ';' |sed -r 's/(.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]]"([^"]+)"$/"\9:\5"/g') ; \
echo ""; \
IFS=""; \
declare -a array="(${search})" ; \
count=$(echo ${#array[@]}); \
echo "$count dans array"; \
for file in "${array[@]}"; do echo "-> $file"; done;

5 dans array
-> /root/Capture d'écran 2024-02-05 195622.png:17K
-> /root/Capture d'écran 2024-02-05 195739.png:46K
-> /root/Capture d'écran 2024-02-05 235843.png:33K
-> /root/Capture d'écran 2024-02-05 235747.png:21K
-> /root/Capture d'écran 2024-02-05 200425.png:40K
root@lb2.ww2:~ #

```

Bonne journée.

---

<div class="post-metadata">

**Author:** ![Verner](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/v/34f0e0/32.png) [@Verner](https://www.debian-fr.org/u/Verner)\
**Post date:** [Octobre 16, 2024, 5:21 UTC](https://www.debian-fr.org/t/parser-les-espaces-du-nom-dun-fichier-sortie-de-find-sed-array/90442/5 "2024-10-16T17:21:04Z")

</div>

> [@anon36725218](#):
>
> ````auto
> find /root/ -type f -name "*.png" -mmin -600 -exec ls -lhQ {} ';' |sed -r 's/(.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]](.*)[[:space:]]"([^"]+)"$/"\9:\5"/g'```
> 
> ````

Bien que awk aurait été plus judicieux que sed dans cet exemple, il y a quand-même plus direct… et beaucoup moins tordu:

`find <options> -type f -exec du -h '{}' \;`

Pour l’array, l’astuce pour conserver les espaces de nom de fichier est d’utiliser  
`-print0 | xargs -0`  
«&nbsp;`for file in "${array[@]}; do`&nbsp;» comprendra que le séparateur est un ‹&nbsp;null&nbsp;› character, et non un espace ou retour de ligne.  
voir man find → **Safer ’find -print0 | xargs -0’ approach**

---

<div class="post-metadata">

**Author:** ![anon36725218](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/8e8cbc/32.png) [@anon36725218](https://www.debian-fr.org/u/anon36725218)\
**Post date:** [Octobre 16, 2024, 6:17 UTC](https://www.debian-fr.org/t/parser-les-espaces-du-nom-dun-fichier-sortie-de-find-sed-array/90442/6 "2024-10-16T18:17:37Z")

</div>

Je n’ai pas tout compris mais je regarderais çà. Merci @verner.

---

<div class="post-metadata">

**Author:** ![Verner](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/v/34f0e0/32.png) [@Verner](https://www.debian-fr.org/u/Verner)\
**Post date:** [Octobre 16, 2024, 6:29 UTC](https://www.debian-fr.org/t/parser-les-espaces-du-nom-dun-fichier-sortie-de-find-sed-array/90442/7 "2024-10-16T18:29:22Z")

</div>

Le problème des noms à espace est un grand classique avec find.  
«&nbsp;`find -print0`&nbsp;» sortira une ligne type ‹&nbsp;fichier1fichier2fichier3&nbsp;› qui parait illisible puisque fichier1 et fichier2 sont séparés par un caractère invisible qui sera parfaitement compris par `xargs -0`.

> man xargs  
> -0, --null :  
> Input items are terminated by a null character instead of by whitespace

Comme le séparateur est invisible, il faut voir pour le croire…

ps: quel drôle d’idée ce type de nom de fichier à espaces: «&nbsp;Capture d’écran 2024-02-05 195739.png&nbsp;»  
«&nbsp;Capture\_écran\_2024-02-05\_195739.png&nbsp;» est quand-même plus judicieux.

---

<div class="post-metadata">

**Author:** ![anon36725218](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/8e8cbc/32.png) [@anon36725218](https://www.debian-fr.org/u/anon36725218)\
**Post date:** [Octobre 16, 2024, 6:35 UTC](https://www.debian-fr.org/t/parser-les-espaces-du-nom-dun-fichier-sortie-de-find-sed-array/90442/8 "2024-10-16T18:35:50Z")

</div>

> [@Verner](#):
>
> ps: quel drôle d’idée ce type de nom de fichier à espaces: « Capture d’écran 2024-02-05 195739.png »  
> « Capture\_écran\_2024-02-05\_195739.png » est quand-même plus judicieux.

On fait des image (capture d’écran) pour les partager sur lle web ; (c’est depuis mon poste windows l’imprime écran et (aussi) vidéo dans win11 c’est fun pour enregistrer rapidement le bureau).

> [@Verner](#):
>
> Le problème des noms à espace est un grand classique avec find.  
> « `find -print0` » sortira une ligne type ‹ fichier1fichier2fichier3 › qui parait illisible puisque fichier1 et fichier2 sont séparés par un caractère invisible qui sera parfaitement compris par `xargs -0` .
> 
> > man xargs  
> > -0, --null :  
> > Input items are terminated by a null character instead of by whitespace
> 
> Comme le séparateur est invisible, il faut voir pour le croire…

Ouais il faut que je vois çà – comme je le disais.

Merci @verner !
