Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Script dos2unix ultra portable

23 réponses
Avatar
Stephane Gibier
Salut,

Je souhaite intégrer dans un script d'installation (install.sh) une
méthode le plus portable possible pour transformer des fichiers *.ini du
format 'DOS' (CR/LF) au format 'Unix' (LF). Pour le moment, j'utilise le
bout de script suivant qui fonctionne très bien sous Linux :

find . -name '*.ini' -exec sh -c 'sed 's/.$//' <{} >{}~; mv {}~ {}' \;

Cela ne fonctionne pas sous AIX 4.3 car le 'joker' {} n'est pas
substitué dans ce cas là. Je recherche donc un moyen hyper portable pour
effectuer cette bête transformation, sans utiliser perl, avec les moyens
posix du bord (find, sed, sh)

Auriez vous une idée ?

Merci

--
Stéphane Gibier <stephane@gibier.org>
Le maniement réitéré des fonds multiplie les mouvements de caisse
Yr znavrzrag eévgéeé qrf pbaf zhygvcyvr yrf zbhirzragf qr srffr

10 réponses

1 2 3
Avatar
Laurent Wacrenier
Stephane Gibier écrit:
Je souhaite intégrer dans un script d'installation (install.sh) une
méthode le plus portable possible pour transformer des fichiers *.ini du
format 'DOS' (CR/LF) au format 'Unix' (LF). Pour le moment, j'utilise le
bout de script suivant qui fonctionne très bien sous Linux :

find . -name '*.ini' -exec sh -c 'sed 's/.$//' <{} >{}~; mv {}~ {}' ;

Cela ne fonctionne pas sous AIX 4.3 car le 'joker' {} n'est pas
substitué dans ce cas là. Je recherche donc un moyen hyper portable pour
effectuer cette bête transformation, sans utiliser perl, avec les moyens
posix du bord (find, sed, sh)


Utilise "tr -d 'r'".
Sinon, celà ne bugerait t'il pas parce que les "'" s'entremèlent ?

Avatar
Stephane Gibier

Stephane Gibier écrit:

find . -name '*.ini' -exec sh -c 'sed 's/.$//' <{} >{}~; mv {}~ {}' ;


Utilise "tr -d 'r'".


J'y ai pensé mais je pense que sed est plus facilement disponible sous
les Unix actuels du marché (AIX, HP/UX, Solaris et Linux). Enfin, je
peux me gourrer...

Sinon, celà ne bugerait t'il pas parce que les "'" s'entremèlent ?


Fort possible effectivement mais j'avoue que je m'y perd un peu avec les
substitutions : si j'ai bien compris, c'est find qui s'occupe de
substituer {} par le nom du fichier trouvé. Est-ce bien cela ? Je n'ai
pas de AIX sous la main ce soir, mais sous mon Linux, les 2 commandes
suivantes sont équivalentes :

find . -exec sh -c "echo {}" ;
find . -exec sh -c 'echo {}' ;

En fait, je suis coincé par le fait que sed ne remplace pas le fichier
et que le résultat sorte sur stdout. Je suis donc obligé de passer par
un subshell (sh -c) pour rediriger stdout.

--
Stéphane Gibier
L'épicurien cherche les sources du bonheur
Y'écvphevra purepur yrf obhefrf qh fbaarhe


Avatar
Pascal Bourguignon
Laurent Wacrenier <lwa@ teaser . fr> writes:

Stephane Gibier écrit:
Je souhaite intégrer dans un script d'installation (install.sh) une
méthode le plus portable possible pour transformer des fichiers *.ini du
format 'DOS' (CR/LF) au format 'Unix' (LF). Pour le moment, j'utilise le
bout de script suivant qui fonctionne très bien sous Linux :

find . -name '*.ini' -exec sh -c 'sed 's/.$//' <{} >{}~; mv {}~ {}' ;

Cela ne fonctionne pas sous AIX 4.3 car le 'joker' {} n'est pas
substitué dans ce cas là. Je recherche donc un moyen hyper portable pour
effectuer cette bête transformation, sans utiliser perl, avec les moyens
posix du bord (find, sed, sh)


Utilise "tr -d 'r'".
Sinon, celà ne bugerait t'il pas parce que les "'" s'entremèlent ?


Non, dans ces cas là, le plus simple (en excluant les noms de fichier
contenant un newline) est:

find . -name '*.ini' -print
| while read file ; do
cp "$file" "$file"~
&& sed 's/.$//' < "$file"~ > "$file" # ou tr si on préfère
done

Noter l'usage de cp à la place de mv qui permet de conserver les
droits d'accès et propriétaire et groupe des fichiers.

--
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.


Avatar
Pascal Bourguignon
Stephane Gibier writes:


Stephane Gibier écrit:

find . -name '*.ini' -exec sh -c 'sed 's/.$//' <{} >{}~; mv {}~ {}' ;


Utilise "tr -d 'r'".


J'y ai pensé mais je pense que sed est plus facilement disponible sous
les Unix actuels du marché (AIX, HP/UX, Solaris et Linux). Enfin, je
peux me gourrer...

Sinon, celà ne bugerait t'il pas parce que les "'" s'entremèlent ?


Fort possible effectivement mais j'avoue que je m'y perd un peu avec les
substitutions : si j'ai bien compris, c'est find qui s'occupe de
substituer {} par le nom du fichier trouvé. Est-ce bien cela ?


Oui, mais ça n'a aucun rapport.

find . -name '*.ini' -exec sh -c 'sed 's/.$//' <{} >{}~; mv {}~ {}' ;
ccccccccccccc'''''''ccccccccccccc''''''cccccc''''''''''''''''''''''ccc

Au final, le shell exécute quelque chose comme:

execl("/usr/bin/find",
".",
"-name",
"*.ini",
"-exec",
"sh",
"-c",
"sed s/.$// <{} >{}~; mv {}~ {}",
0);


Je n'ai
pas de AIX sous la main ce soir, mais sous mon Linux, les 2 commandes
suivantes sont équivalentes :

find . -exec sh -c "echo {}" ;
find . -exec sh -c 'echo {}' ;

En fait, je suis coincé par le fait que sed ne remplace pas le fichier
et que le résultat sorte sur stdout. Je suis donc obligé de passer par
un subshell (sh -c) pour rediriger stdout.


Ce qui est bien normal puisque le shell qui exécute la commande find
va aussi interpréter le ; et les < et > que tu essaye de mettre dans
les arguments après -exec.

Dans tous les cas, ;, < et > ne sont pas interprétés par les
commandes, mais uniquement par les shells (en tant que redirections,
certaines commandes peuvent interpréter de tels arguments comme
comparaisons).

C'est pour ça que le terminateur pour les arguments qui constituent la
commande à exécuter par find après -exec, qui est un ;, doit être
précédé d'un antislash: pour éviter qu'il soit interprété par le
shell. On pourrait aussi bien le mettre entre quotes:

find . -exec echo {} ';'


--
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.



Avatar
Laurent Wacrenier
Pascal Bourguignon écrit:

find . -name '*.ini' -print
| while read file ; do
cp "$file" "$file"~
&& sed 's/.$//' < "$file"~ > "$file" # ou tr si on préfère
done

Noter l'usage de cp à la place de mv qui permet de conserver les
droits d'accès et propriétaire et groupe des fichiers.


"cp && sed" ne conserve pas les droits.
Par contre "mv && sed" permet de rattraper une erreur précoce
et de se trouver avec un fichier vide.

Avatar
Stephane CHAZELAS
Le 6 Oct 2003 21:36:55 GMT, Stephane Gibier écrivait :
[...]
find . -name '*.ini' -exec sh -c 'sed 's/.$//' <{} >{}~; mv {}~ {}' ;


Utilise "tr -d 'r'".


J'y ai pensé mais je pense que sed est plus facilement disponible sous
les Unix actuels du marché (AIX, HP/UX, Solaris et Linux).
[...]


Certainement pas, "tr" existait dans les toutes premières
versions d'Unix bien avant sed et est aujourd'hui tout aussi
standard que sed.

find . -name '*.ini' -type f -exec sh -c '
cp "$1" "${1}~" && tr -d 15 < "${1}~" > "$1"' {} {} ;

l'intéret de le faire dans ce sens avec cp est qu'on conserve
les permission et l'i-node du fichier original.

--
Stéphane



Avatar
Stephane CHAZELAS
Le Tue, 7 Oct 2003 09:18:46 +0000 (UTC), Laurent Wacrenier écrivait :
[...]
cp "$file" "$file"~
&& sed 's/.$//' < "$file"~ > "$file" # ou tr si on préfère
done

Noter l'usage de cp à la place de mv qui permet de conserver les
droits d'accès et propriétaire et groupe des fichiers.


"cp && sed" ne conserve pas les droits.


???

« > "$file" » conserve bien les droits l'ownership et l'inode
de "$file". Il n'y a que les modification et change status time
qu'il modifie.

Par contre "mv && sed" permet de rattraper une erreur précoce
et de se trouver avec un fichier vide.


Qu'entends-tu par là ? Quel serait le problème avec "cp && sed"
dans les cas auxquels tu penses ?

--
Stéphane


Avatar
Pascal Bourguignon
Laurent Wacrenier <lwa@ teaser . fr> writes:

Pascal Bourguignon écrit:

find . -name '*.ini' -print
| while read file ; do
cp "$file" "$file"~
&& sed 's/.$//' < "$file"~ > "$file" # ou tr si on préfère
done

Noter l'usage de cp à la place de mv qui permet de conserver les
droits d'accès et propriétaire et groupe des fichiers.


"cp && sed" ne conserve pas les droits.
Par contre "mv && sed" permet de rattraper une erreur précoce
et de se trouver avec un fichier vide.


Là, tu pas perdu une occasion de taire une connerie:

[ sed]$ ls -la
total 17
drwx------ 2 pascal regular 99 Oct 7 13:34 ./
drwxrwxrwt 53 root root 7756 Oct 7 13:35 ../
-rw-rw-r-- 1 lacsap regular 30 Oct 7 13:34 fichier-a-lacsap
-rw-r--r-- 1 pascal regular 30 Oct 7 13:34 fichier-a-pascal
[ sed]$ umask
077
[ sed]$ for f in * ; do mv $f $f~ ; sed -e 's/1/2/g'<$f~ >$f ; done
[ sed]$ ls -l
total 25
drwx------ 2 pascal regular 165 Oct 7 13:35 ./
drwxrwxrwt 53 root root 7756 Oct 7 13:35 ../
-rw------- 1 pascal regular 30 Oct 7 13:35 fichier-a-lacsap
-rw-rw-r-- 1 lacsap regular 30 Oct 7 13:34 fichier-a-lacsap~
-rw------- 1 pascal regular 30 Oct 7 13:35 fichier-a-pascal
-rw-r--r-- 1 pascal regular 30 Oct 7 13:34 fichier-a-pascal~

Oops! Avec mv, fichier-a-lacsap n'appartient plus lacsap, et ses
droits ont été masqués par mon umask.


[ sed]$ cd ../sed2
[ sed2]$ ls -l
total 17
drwx------ 2 pascal regular 99 Oct 7 13:35 ./
drwxrwxrwt 53 root root 7756 Oct 7 13:35 ../
-rw-rw-r-- 1 lacsap regular 30 Oct 7 13:35 fichier-a-lacsap
-rw-r--r-- 1 pascal regular 30 Oct 7 13:35 fichier-a-pascal
[ sed2]$ umask
077
[ sed2]$ for f in * ; do cp $f $f~ ; sed -e 's/1/2/g'<$f~ >$f ; done
[ sed2]$ ls -l
total 25
drwx------ 2 pascal regular 165 Oct 7 13:37 ./
drwxrwxrwt 53 root root 7756 Oct 7 13:35 ../
-rw-rw-r-- 1 lacsap regular 30 Oct 7 13:37 fichier-a-lacsap
-rw------- 1 pascal regular 30 Oct 7 13:37 fichier-a-lacsap~
-rw-r--r-- 1 pascal regular 30 Oct 7 13:37 fichier-a-pascal
-rw------- 1 pascal regular 30 Oct 7 13:37 fichier-a-pascal~

Ici, avec cp, les droits et propriétaire et groupe des fichiers ont
été conservé. Magie?


--
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.


Avatar
Laurent Wacrenier
Stephane CHAZELAS écrit:
Par contre "mv && sed" permet de rattraper une erreur précoce
et de se trouver avec un fichier vide.


Qu'entends-tu par là ? Quel serait le problème avec "cp && sed"
dans les cas auxquels tu penses ?


Si sed a une erreur d'execution, le fichier va être tronqué. Pour ne
pas perdre les données, il va falloir récuperer l'ancien fichier et la
date de dernière mofification va être changée (par cp) alors que le
fichier n'aura pas bougé.


Avatar
Laurent Wacrenier
Pascal Bourguignon écrit:

Ici, avec cp, les droits et propriétaire et groupe des fichiers ont
été conservé. Magie?


Pas le bit 's' normalement.

Et celà se fait au prix d'un trou de sécurité (au cas ou le fichier en
~ existe, éventuelement sous la forme d'un lien symbolique), d'une
copie de données (lourde), d'une modification des dates et du compteur
de liens en cas de rattapage d'erreur.

1 2 3