bash et les expaces dans les noms de fichiers

10 réponses
Avatar
Philippe Delavalade
Bonjour.

J'ai un pépertoire qui contient des sous-répertoires ; dans chacun de ces
derniers j'ai des fichiers sur lesquels je veux faire des opérations
(toujours les mêmes).

J'ai donc envisagé un script du genre

for dir in `find -mindetph 1 -type d`
do
pushd "$dir"
commande1
...
commanden
popd
done

l'option -mindepth est là pour éviter les soucis avec ./

Seulement ça ne marche pas car certains des sous-répertoires comporte une
espace (ou plusieurs) dans leur nom.

J'ai créé à titre d'exemple, un répertoire machin dans lequel j'ai créé
cinq sous-répertoires.

voici ce que ça donne

philippe:~/machin$ for dir in `find -mindepth 1 -type d`
> do
> echo "$dir"
> done
./blu
blu
blu
./ble
ble
ble
./bli
bli
bli
./bla
bla
bla
./blo
blo
blo

En fait les noms sont « splités » et donc ça ne marche pas.

Autre essai :

philippe:~/machin$ for dir in "`find -mindepth 1 -type d`"
> do
> echo "$dir"
> done
./blu blu blu
./ble ble ble
./bli bli bli
./bla bla bla
./blo blo blo

Là ça paraît mieux, j'ai bien les cinq sous-répertoires mais :

philippe:~/machin$ for dir in "`find -mindepth 1 -type d`"
> do
> echo "$dir"
> pushd "$dir"
> echo "On est dans `pwd`"
> popd
> done
./blu blu blu
./ble ble ble
./bli bli bli
./bla bla bla
./blo blo blo
bash: pushd: ./blu blu blu
./ble ble ble
./bli bli bli
./bla bla bla
./blo blo blo: Aucun fichier ou dossier de ce type
On est dans /home/philippe/machin
bash: popd: pile de répertoire vide

Là ça se passe comme s'il n'y avait qu'un seul sous-répertoire dans machin
(une sorte de concaténation des cinq noms).

J'ai, à tout hasard, essayé avec "${dir}" au lieu de "$dir" mais c'est la
même chose.

J'ai cherché dans abs-guide mais je n'ai rien trouvé comme idée nouvelle.

J'ai bien la possibilité de faire un
rename 's/ /#/g' *
mais c'est du bricolage...

Quelqu'un aurait-il une suggestion plus académique ?

Merci d'avance.

--
Ph. Delavalade

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers debian-user-french-REQUEST@lists.debian.org
En cas de soucis, contactez EN ANGLAIS listmaster@lists.debian.org
Archive: http://lists.debian.org/20130212180144.GA13363@magellan

10 réponses

Avatar
Sébastien MARQUE
Bonsoir,

L'origine de ton problème est l'IFS.

Tu peux essayer de faire IFS=$(echo -ne "nb"):

$ for i in foo bar baz; do mkdir "foo $i"; done

$ IFS=$(echo -en "nb")

$ for i in $(find . -mindepth 1 -type d); do echo $i; done
./foo baz
./foo bar
./foo foo

hope this helps.

Séb

Le 12/02/2013 19:01, Philippe Delavalade a écrit :
Bonjour.

J'ai un pépertoire qui contient des sous-répertoires ; dans chacun de ces
derniers j'ai des fichiers sur lesquels je veux faire des opérations
(toujours les mêmes).

J'ai donc envisagé un script du genre

for dir in `find -mindetph 1 -type d`
do
pushd "$dir"
commande1
...
commanden
popd
done

l'option -mindepth est là pour éviter les soucis avec ./

Seulement ça ne marche pas car certains des sous-répertoires comporte une
espace (ou plusieurs) dans leur nom.

J'ai créé à titre d'exemple, un répertoire machin dans lequel j'ai créé
cinq sous-répertoires.

voici ce que ça donne

philippe:~/machin$ for dir in `find -mindepth 1 -type d`
do
echo "$dir"
done


./blu
blu
blu
./ble
ble
ble
./bli
bli
bli
./bla
bla
bla
./blo
blo
blo

En fait les noms sont « splités » et donc ça ne marche pas.

Autre essai :

philippe:~/machin$ for dir in "`find -mindepth 1 -type d`"
do
echo "$dir"
done


./blu blu blu
./ble ble ble
./bli bli bli
./bla bla bla
./blo blo blo

Là ça paraît mieux, j'ai bien les cinq sous-répertoires mais :

philippe:~/machin$ for dir in "`find -mindepth 1 -type d`"
do
echo "$dir"
pushd "$dir"
echo "On est dans `pwd`"
popd
done


./blu blu blu
./ble ble ble
./bli bli bli
./bla bla bla
./blo blo blo
bash: pushd: ./blu blu blu
./ble ble ble
./bli bli bli
./bla bla bla
./blo blo blo: Aucun fichier ou dossier de ce type
On est dans /home/philippe/machin
bash: popd: pile de répertoire vide

Là ça se passe comme s'il n'y avait qu'un seul sous-répertoire dans machin
(une sorte de concaténation des cinq noms).

J'ai, à tout hasard, essayé avec "${dir}" au lieu de "$dir" mais c'est la
même chose.

J'ai cherché dans abs-guide mais je n'ai rien trouvé comme idée nouvelle.

J'ai bien la possibilité de faire un
rename 's/ /#/g' *
mais c'est du bricolage...

Quelqu'un aurait-il une suggestion plus académique ?

Merci d'avance.




--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/
Avatar
Thuban
Bonsoir,
Il faut en effet modifier l'IFS (internal file separator) pour manipuler
les noms avec espaces.

#!/bin/sh
# Se souvenir de l'ancien IFS
OLDIFS=$IFS
# Modification de l'IFS : retour à la ligne
IFS='
'

# quelques opérations
...
...

# On rétablit l'IFS
IFS=$OLDIFS

exit 0


Le 20:02:39 le 12 févr. 2013 , Sébastien MARQUE a écrit :
Bonsoir,

L'origine de ton problème est l'IFS.

Tu peux essayer de faire IFS=$(echo -ne "nb"):

$ for i in foo bar baz; do mkdir "foo $i"; done

$ IFS=$(echo -en "nb")

$ for i in $(find . -mindepth 1 -type d); do echo $i; done
./foo baz
./foo bar
./foo foo

hope this helps.

Séb

Le 12/02/2013 19:01, Philippe Delavalade a écrit :
>Bonjour.
>
>J'ai un pépertoire qui contient des sous-répertoires ; dans chacun de ces
>derniers j'ai des fichiers sur lesquels je veux faire des opérations
>(toujours les mêmes).
>
>J'ai donc envisagé un script du genre
>
>for dir in `find -mindetph 1 -type d`
>do
> pushd "$dir"
> commande1
> ...
> commanden
> popd
>done
>
>l'option -mindepth est là pour éviter les soucis avec ./
>
>Seulement ça ne marche pas car certains des sous-répertoires comporte une
>espace (ou plusieurs) dans leur nom.
>
>J'ai créé à titre d'exemple, un répertoire machin dans lequel j'ai créé
>cinq sous-répertoires.
>
>voici ce que ça donne
>
>philippe:~/machin$ for dir in `find -mindepth 1 -type d`
>>do
>> echo "$dir"
>>done
>./blu
>blu
>blu
>./ble
>ble
>ble
>./bli
>bli
>bli
>./bla
>bla
>bla
>./blo
>blo
>blo
>
>En fait les noms sont « splités » et donc ça ne marche pas.
>
>Autre essai :
>
>philippe:~/machin$ for dir in "`find -mindepth 1 -type d`"
>>do
>> echo "$dir"
>>done
>./blu blu blu
>./ble ble ble
>./bli bli bli
>./bla bla bla
>./blo blo blo
>
>Là ça paraît mieux, j'ai bien les cinq sous-répertoires mais :
>
>philippe:~/machin$ for dir in "`find -mindepth 1 -type d`"
>>do
>> echo "$dir"
>> pushd "$dir"
>> echo "On est dans `pwd`"
>> popd
>>done
>./blu blu blu
>./ble ble ble
>./bli bli bli
>./bla bla bla
>./blo blo blo
>bash: pushd: ./blu blu blu
>./ble ble ble
>./bli bli bli
>./bla bla bla
>./blo blo blo: Aucun fichier ou dossier de ce type
>On est dans /home/philippe/machin
>bash: popd: pile de répertoire vide
>
>Là ça se passe comme s'il n'y avait qu'un seul sous-répertoire dans machin
>(une sorte de concaténation des cinq noms).
>
>J'ai, à tout hasard, essayé avec "${dir}" au lieu de "$dir" mais c'est la
>même chose.
>
>J'ai cherché dans abs-guide mais je n'ai rien trouvé comme idée nouvelle.
>
>J'ai bien la possibilité de faire un
>rename 's/ /#/g' *
>mais c'est du bricolage...
>
>Quelqu'un aurait-il une suggestion plus académique ?
>
>Merci d'avance.
>

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/




--
,--. Xavier Cartron
: /` ) M2 MEFPC
| `-' Debian user
_ jabber :

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/
Avatar
Jean-Damien Durand
Hello,

find -mindepth 1 -type d -execdir commande1 ; -execdir commande2 ; etc... -execdir commanden ;

peut-etre -;

@+, JD.

Bonsoir,
Il faut en effet modifier l'IFS (internal file separator) pour manipuler
les noms avec espaces.

Le 20:02:39 le 12 févr. 2013 , Sébastien MARQUE a écrit :
> L'origine de ton problème est l'IFS.
>
> Le 12/02/2013 19:01, Philippe Delavalade a écrit :
> >J'ai un pépertoire qui contient des sous-répertoires ; dans chacun de ces
> >derniers j'ai des fichiers sur lesquels je veux faire des opérations
> >(toujours les mêmes).



--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/
Avatar
Bernard Schoenacker
Le Tue, 12 Feb 2013 19:01:44 +0100,
Philippe Delavalade a écrit :

Bonjour.

J'ai un répertoire qui contient des sous-répertoires ; dans chacun de
ces derniers j'ai des fichiers sur lesquels je veux faire des
opérations (toujours les mêmes).

J'ai donc envisagé un script du genre

for dir in `find -mindetph 1 -type d`
do
pushd "$dir"
commande1
...
commanden
popd
done

l'option -mindepth est là pour éviter les soucis avec ./

Seulement ça ne marche pas car certains des sous-répertoires comporte
une espace (ou plusieurs) dans leur nom.

J'ai créé à titre d'exemple, un répertoire machin dans lequel j'ai
créé cinq sous-répertoires.

voici ce que ça donne

philippe:~/machin$ for dir in `find -mindepth 1 -type d`
> do
> echo "$dir"
> done
./blu
blu
blu
./ble
ble
ble
./bli
bli
bli
./bla
bla
bla
./blo
blo
blo

En fait les noms sont « splités » et donc ça ne marche pas.

Autre essai :

philippe:~/machin$ for dir in "`find -mindepth 1 -type d`"
> do
> echo "$dir"
> done
./blu blu blu
./ble ble ble
./bli bli bli
./bla bla bla
./blo blo blo

Là ça paraît mieux, j'ai bien les cinq sous-répertoires mais :

philippe:~/machin$ for dir in "`find -mindepth 1 -type d`"
> do
> echo "$dir"
> pushd "$dir"
> echo "On est dans `pwd`"
> popd
> done
./blu blu blu
./ble ble ble
./bli bli bli
./bla bla bla
./blo blo blo
bash: pushd: ./blu blu blu
./ble ble ble
./bli bli bli
./bla bla bla
./blo blo blo: Aucun fichier ou dossier de ce type
On est dans /home/philippe/machin
bash: popd: pile de répertoire vide

Là ça se passe comme s'il n'y avait qu'un seul sous-répertoire dans
machin (une sorte de concaténation des cinq noms).

J'ai, à tout hasard, essayé avec "${dir}" au lieu de "$dir" mais
c'est la même chose.

J'ai cherché dans abs-guide mais je n'ai rien trouvé comme idée
nouvelle.

J'ai bien la possibilité de faire un
rename 's/ /#/g' *
mais c'est du bricolage...

Quelqu'un aurait-il une suggestion plus académique ?

Merci d'avance.



bonjour,

pourquoi ne pas employer "détox" pour lier les espaces ?

apt-cache search detox
detox - utility to replace problematic characters in filenames

http://linux.die.net/man/1/detox

slt
bernard

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/
Avatar
Alex Foulon
Bonjour,

Le Tue, 12 Feb 2013 22:38:22 +0100,
"Jean-Damien Durand" a écrit :

find -mindepth 1 -type d -execdir commande1 ; -execdir commande2 ;
etc... -execdir commanden ;




En utilisant find avec une boucle while on obtient aussi le résultat
escompté :

$ find -mindepth 1 -type d | while read d; do echo "dir: $d"; done

--
Alex

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/
Avatar
Philippe Delavalade
Merci pour toutes les réponses.

Je vais jeter un coup d'œil à detox (jamais entendu parler) mais je vais
surtout m'intéresser à $IFS ; je subodorais déjà que ça pouvait être une
piste mais il faut que je creuse car cette variable me paraît un peu
mystérieuse :-)

Encore merci.

--
Ph. Delavalade

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/
Avatar
J
Le mercredi 13 février 2013 à 16:31 +0100, Philippe Delavalade a écrit :
Je vais jeter un coup d'œil à detox (jamais entendu parler)



Detox n'est pas très souple à mon souvenir. Un petit script personnel en
python ou autre...

Sinon en graphique, il y a fslint qui rend un certains nombre de
services à ceux qui ne sont pas stakhanoviens des regex et pour des
usages ponctuels.

http://en.flossmanuals.net/FSlint/


--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/
Avatar
Bernard Schoenacker
Le Thu, 14 Feb 2013 17:54:41 +0100,
Jérôme a écrit :

Le mercredi 13 février 2013 à 16:31 +0100, Philippe Delavalade a
écrit :
> Je vais jeter un coup d'œil à detox (jamais entendu parler)

Detox n'est pas très souple à mon souvenir. Un petit script personnel
en python ou autre...

Sinon en graphique, il y a fslint qui rend un certains nombre de
services à ceux qui ne sont pas stakhanoviens des regex et pour des
usages ponctuels. ^^^^^^^^^^^^^

http://en.flossmanuals.net/FSlint/




bonjour,


stakhanoviste existe mais pas l'autre

slt
bernard

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/
Avatar
mouss
Le 12/02/2013 19:01, Philippe Delavalade a écrit :
Bonjour.

J'ai un pépertoire qui contient des sous-répertoires ; dans chacun de ces
derniers j'ai des fichiers sur lesquels je veux faire des opérations
(toujours les mêmes).

J'ai donc envisagé un script du genre

for dir in `find -mindetph 1 -type d`
do
pushd "$dir"
commande1
...
commanden
popd
done

l'option -mindepth est là pour éviter les soucis avec ./

Seulement ça ne marche pas car certains des sous-répertoires comporte une
espace (ou plusieurs) dans leur nom.



ton find sort les résultats comme il faut, mais après 'in' ne sait plus
faire la différence entre les espaces séparant les résultats de find et
ceux qui sont dans les noms de répertoire.

mais une bonne pipe (;-p) et tout est repeuplé :

find ... | while read dir; do
macommande "$dir"
...
done


bien sûr, le défaut est que les actions sont dans un sous shell (elles
sont sous la pipe;-p). donc ça marche pas si tu veux que ta commande aie
une action sur ton shell courant. on s'en sort avec des echo foobar dans
le fils, que le père (ou la mère?) interprète et exécute.



--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/
Avatar
Sylvain L. Sauvage
Le vendredi 15 février 2013 à 00:26:42, mouss a écrit :
[… | while read …]
bien sûr, le défaut est que les actions sont dans un sous
shell (elles sont sous la pipe;-p). donc ça marche pas si tu
veux que ta commande aie une action sur ton shell courant.
on s'en sort avec des echo foobar dans le fils, que le père
(ou la mère?) interprète et exécute.



On peut éviter ça en Bash : enrober le `find` dans des
guillemets.

mkdir "a a" "b b"
for f in "`find . -type d`"; do
echo "$f"
done
→
.
./a a
./b b

Chaque ligne de la sortie est protégée, pas toute la sortie.
C’est le même comportement que pour "$@", sauf que pour $@,
c’est chaque $n, pas chaque ligne.


Attention ! C’est un bashisme. Dash p.ex., protège toute l a
sortie → ". ./a a ./b b"…

--
Sylvain Sauvage

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/