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 :
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
Ici, avec cp, les droits et propriétaire et groupe des fichiers ont été conservé. Magie?
Pas le bit 's' normalement.
Mais normalement les bits 's' ne sont pas à 1.
-- __Pascal_Bourguignon__ http://www.informatimago.com/ Do not adjust your mind, there is a fault in reality.
Stephane Gibier
Certainement pas, "tr" existait dans les toutes premières versions d'Unix bien avant sed et est aujourd'hui tout aussi standard que sed.
Ok, je le note...
<troll> Le problème (!) avec Linux, c'est qu'on a l'impression que tous les Unix sont identiques :-) Et quand on tombe au boulot avec un AIX sans pages de man, galère. Et si c'est chez un client... </troll>
Elégant ! Mais je ne comprend pas pourquoi {} {}. Un seul suffit pour qu'il soit substitué en $1 dans le subshell non ?
l'intéret de le faire dans ce sens avec cp est qu'on conserve les permission et l'i-node du fichier original.
Exact.
-- Stéphane Gibier Le maniement réitéré des fonds multiplie les mouvements de caisse Yr znavrzrag eévgéeé qrf pbaf zhygvcyvr yrf zbhirzragf qr srffr
Certainement pas, "tr" existait dans les toutes premières
versions d'Unix bien avant sed et est aujourd'hui tout aussi
standard que sed.
Ok, je le note...
<troll>
Le problème (!) avec Linux, c'est qu'on a l'impression que tous les Unix
sont identiques :-) Et quand on tombe au boulot avec un AIX sans pages
de man, galère. Et si c'est chez un client...
</troll>
Elégant ! Mais je ne comprend pas pourquoi {} {}. Un seul suffit pour
qu'il soit substitué en $1 dans le subshell non ?
l'intéret de le faire dans ce sens avec cp est qu'on conserve
les permission et l'i-node du fichier original.
Exact.
--
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
Certainement pas, "tr" existait dans les toutes premières versions d'Unix bien avant sed et est aujourd'hui tout aussi standard que sed.
Ok, je le note...
<troll> Le problème (!) avec Linux, c'est qu'on a l'impression que tous les Unix sont identiques :-) Et quand on tombe au boulot avec un AIX sans pages de man, galère. Et si c'est chez un client... </troll>
Elégant ! Mais je ne comprend pas pourquoi {} {}. Un seul suffit pour qu'il soit substitué en $1 dans le subshell non ? [...]
Suivant le sh
sh -c 'echo "$0" "$1"' A B
donnera "sh A" ou "A B"
sh -c 'echo "$1"' A A
donnera A pour les deux types de sh.
-- Stéphane
Stephane CHAZELAS
Le 7 Oct 2003 19:58:53 GMT, Stephane Gibier écrivait :
find . -name '*.ini' -print | while read file ; do cp "$file" "$file"~ && sed 's/.$//' < "$file"~ > "$file" # ou tr si on préfère done
Génial ! J'avais complètement oublié le coup du "while read" ! Pas de subshell, pipé et ultra portable. [...]
Note qu'il faut remplacer "read file" par "IFS= read -r file" ou tu auras des soucis avec les noms de fichiers contenant dans backslashes ou se finissant par des caractères blancs. Et comme l'a dit Pascal, tu auras toujours des problèmes avec les noms de fichiers contenant des NL.
"read -r" n'est pas des plus portables en plus. Donc, faudrait faire:
find ... | sed 's//&&/g' | while IFS= read file;....
Vaut mieux utiliser le -exec sh -c ...
-- Stéphane
Le 7 Oct 2003 19:58:53 GMT, Stephane Gibier <stephane@gibier.org> écrivait :
find . -name '*.ini' -print
| while read file ; do
cp "$file" "$file"~
&& sed 's/.$//' < "$file"~ > "$file" # ou tr si on préfère
done
Génial ! J'avais complètement oublié le coup du "while read" ! Pas de
subshell, pipé et ultra portable.
[...]
Note qu'il faut remplacer "read file" par "IFS= read -r file" ou
tu auras des soucis avec les noms de fichiers contenant dans
backslashes ou se finissant par des caractères blancs. Et comme
l'a dit Pascal, tu auras toujours des problèmes avec les noms de
fichiers contenant des NL.
"read -r" n'est pas des plus portables en plus. Donc, faudrait
faire:
find ... | sed 's/\/&&/g' | while IFS= read file;....
Le 7 Oct 2003 19:58:53 GMT, Stephane Gibier écrivait :
find . -name '*.ini' -print | while read file ; do cp "$file" "$file"~ && sed 's/.$//' < "$file"~ > "$file" # ou tr si on préfère done
Génial ! J'avais complètement oublié le coup du "while read" ! Pas de subshell, pipé et ultra portable. [...]
Note qu'il faut remplacer "read file" par "IFS= read -r file" ou tu auras des soucis avec les noms de fichiers contenant dans backslashes ou se finissant par des caractères blancs. Et comme l'a dit Pascal, tu auras toujours des problèmes avec les noms de fichiers contenant des NL.
"read -r" n'est pas des plus portables en plus. Donc, faudrait faire:
find ... | sed 's//&&/g' | while IFS= read file;....
Vaut mieux utiliser le -exec sh -c ...
-- Stéphane
Pascal Bourguignon
Stephane Gibier writes:
Certainement pas, "tr" existait dans les toutes premières versions d'Unix bien avant sed et est aujourd'hui tout aussi standard que sed.
Ok, je le note...
<troll> Le problème (!) avec Linux, c'est qu'on a l'impression que tous les Unix sont identiques :-) Et quand on tombe au boulot avec un AIX sans pages de man, galère. Et si c'est chez un client... </troll>
Elégant ! Mais je ne comprend pas pourquoi {} {}. Un seul suffit pour qu'il soit substitué en $1 dans le subshell non ?
Mais j'ai l'impression qu'on y forke plus qu'avec ma solution:
find . -name *.init -type f -print | while read f ; do cp $f $f~ && tr -d 15 < $f~ > $f ; done
Quand le while (ou autre structure de contrôle shell) est en dernière position d'un pipe, le shell exécute lui même cette structure de contrôle au lieu de forker un sous-shell.
-- __Pascal_Bourguignon__ http://www.informatimago.com/ Do not adjust your mind, there is a fault in reality.
Stephane Gibier <stephane@gibier.org> writes:
Certainement pas, "tr" existait dans les toutes premières
versions d'Unix bien avant sed et est aujourd'hui tout aussi
standard que sed.
Ok, je le note...
<troll>
Le problème (!) avec Linux, c'est qu'on a l'impression que tous les Unix
sont identiques :-) Et quand on tombe au boulot avec un AIX sans pages
de man, galère. Et si c'est chez un client...
</troll>
Elégant ! Mais je ne comprend pas pourquoi {} {}. Un seul suffit pour
qu'il soit substitué en $1 dans le subshell non ?
Mais j'ai l'impression qu'on y forke plus qu'avec ma solution:
find . -name *.init -type f -print
| while read f ; do cp $f $f~ && tr -d 15 < $f~ > $f ; done
Quand le while (ou autre structure de contrôle shell) est en dernière
position d'un pipe, le shell exécute lui même cette structure de
contrôle au lieu de forker un sous-shell.
--
__Pascal_Bourguignon__
http://www.informatimago.com/
Do not adjust your mind, there is a fault in reality.
Certainement pas, "tr" existait dans les toutes premières versions d'Unix bien avant sed et est aujourd'hui tout aussi standard que sed.
Ok, je le note...
<troll> Le problème (!) avec Linux, c'est qu'on a l'impression que tous les Unix sont identiques :-) Et quand on tombe au boulot avec un AIX sans pages de man, galère. Et si c'est chez un client... </troll>
Elégant ! Mais je ne comprend pas pourquoi {} {}. Un seul suffit pour qu'il soit substitué en $1 dans le subshell non ?
Mais j'ai l'impression qu'on y forke plus qu'avec ma solution:
find . -name *.init -type f -print | while read f ; do cp $f $f~ && tr -d 15 < $f~ > $f ; done
Quand le while (ou autre structure de contrôle shell) est en dernière position d'un pipe, le shell exécute lui même cette structure de contrôle au lieu de forker un sous-shell.
-- __Pascal_Bourguignon__ http://www.informatimago.com/ Do not adjust your mind, there is a fault in reality.
Stephane CHAZELAS
Le 07 Oct 2003 20:28:55 GMT, Stephane CHAZELAS écrivait : [...]
Vaut mieux utiliser le -exec sh -c ...
Et note, que pour etre pédant et minimiser le nombre de commandes lancées tout en étant portable, on peut faire:
find ./. ( -name '*.ini' -o -name '.*.ini' -o -name .ini ) -type f -print | sed 's/./&/g' | awk ' { if (NR > 1) { printf("%s", line) if ($0 !~ //.//) printf("") print "" } line = $0 } END { print line }' | xargs sh -c 'shift "$1" for file do cp "$file" "${file}~" && tr -d 15 < "${file}~" > "$file" done' 2 1
C'qu'on se marre avec le shell quand-meme !
-- Stéphane
Le 07 Oct 2003 20:28:55 GMT, Stephane CHAZELAS <stephane_chazelas@yahoo.fr> écrivait :
[...]
Vaut mieux utiliser le -exec sh -c ...
Et note, que pour etre pédant et minimiser le nombre de
commandes lancées tout en étant portable, on peut faire:
find ./. ( -name '*.ini' -o -name '.*.ini' -o -name .ini )
-type f -print | sed 's/./\&/g' | awk '
{
if (NR > 1) {
printf("%s", line)
if ($0 !~ //\.\//)
printf("\")
print ""
}
line = $0
}
END {
print line
}' | xargs sh -c 'shift "$1"
for file
do cp "$file" "${file}~" && tr -d \15 < "${file}~" > "$file"
done' 2 1
Mais j'ai l'impression qu'on y forke plus qu'avec ma solution:
find . -name *.init -type f -print | while read f ; do cp $f $f~ && tr -d 15 < $f~ > $f ; done
On n'y forke pas plus (1 + 2n dans les deux cas voire 2 + 2n pour la tienne, faudra peut-etre remplacer "tr" par "exec tr" avec la mienne pour éviter le 1 + 3n avec certains sh), mais on lance plus de commandes (1 shell par fichier).
Quand le while (ou autre structure de contrôle shell) est en dernière position d'un pipe, le shell exécute lui même cette structure de contrôle au lieu de forker un sous-shell.
Ça dépend des shells. bash/pdksh s'opposent à zsh/ksh là dessus.
-- Stéphane
Le 07 Oct 2003 22:59:30 +0200, Pascal Bourguignon <spam@thalassa.informatimago.com> écrivait :
[...]
Mais j'ai l'impression qu'on y forke plus qu'avec ma solution:
find . -name *.init -type f -print
| while read f ; do cp $f $f~ && tr -d 15 < $f~ > $f ; done
On n'y forke pas plus (1 + 2n dans les deux cas voire 2 + 2n
pour la tienne, faudra peut-etre remplacer "tr" par "exec tr"
avec la mienne pour éviter le 1 + 3n avec certains sh), mais on
lance plus de commandes (1 shell par fichier).
Quand le while (ou autre structure de contrôle shell) est en dernière
position d'un pipe, le shell exécute lui même cette structure de
contrôle au lieu de forker un sous-shell.
Ça dépend des shells. bash/pdksh s'opposent à zsh/ksh là dessus.
Mais j'ai l'impression qu'on y forke plus qu'avec ma solution:
find . -name *.init -type f -print | while read f ; do cp $f $f~ && tr -d 15 < $f~ > $f ; done
On n'y forke pas plus (1 + 2n dans les deux cas voire 2 + 2n pour la tienne, faudra peut-etre remplacer "tr" par "exec tr" avec la mienne pour éviter le 1 + 3n avec certains sh), mais on lance plus de commandes (1 shell par fichier).
Quand le while (ou autre structure de contrôle shell) est en dernière position d'un pipe, le shell exécute lui même cette structure de contrôle au lieu de forker un sous-shell.
Ça dépend des shells. bash/pdksh s'opposent à zsh/ksh là dessus.
-- Stéphane
Pascal Bourguignon
Stephane CHAZELAS writes:
Le 07 Oct 2003 20:28:55 GMT, Stephane CHAZELAS écrivait : [...]
Vaut mieux utiliser le -exec sh -c ...
Et note, que pour etre pédant et minimiser le nombre de commandes lancées tout en étant portable, on peut faire:
find ./. ( -name '*.ini' -o -name '.*.ini' -o -name .ini ) -type f -print | sed 's/./&/g' | awk ' { if (NR > 1) { printf("%s", line) if ($0 !~ //.//) printf("") print "" } line = $0 } END { print line }' | xargs sh -c 'shift "$1" for file do cp "$file" "${file}~" && tr -d 15 < "${file}~" > "$file" done' 2 1
C'qu'on se marre avec le shell quand-meme !
Oulala! Mais il y a des sacrés différences avec les awk, gawk, nawk... Je me demande si c'est pas pire que les sh A B ou sh A A...
-- __Pascal_Bourguignon__ http://www.informatimago.com/ Do not adjust your mind, there is a fault in reality.
Mais j'ai l'impression qu'on y forke plus qu'avec ma solution:
find . -name *.init -type f -print | while read f ; do cp $f $f~ && tr -d 15 < $f~ > $f ; done
On n'y forke pas plus (1 + 2n dans les deux cas voire 2 + 2n pour la tienne, faudra peut-etre remplacer "tr" par "exec tr" avec la mienne pour éviter le 1 + 3n avec certains sh), mais on lance plus de commandes (1 shell par fichier).
Mais j'ai l'impression qu'on y forke plus qu'avec ma solution:
find . -name *.init -type f -print
| while read f ; do cp $f $f~ && tr -d 15 < $f~ > $f ; done
On n'y forke pas plus (1 + 2n dans les deux cas voire 2 + 2n
pour la tienne, faudra peut-etre remplacer "tr" par "exec tr"
avec la mienne pour éviter le 1 + 3n avec certains sh), mais on
lance plus de commandes (1 shell par fichier).
Mais j'ai l'impression qu'on y forke plus qu'avec ma solution:
find . -name *.init -type f -print | while read f ; do cp $f $f~ && tr -d 15 < $f~ > $f ; done
On n'y forke pas plus (1 + 2n dans les deux cas voire 2 + 2n pour la tienne, faudra peut-etre remplacer "tr" par "exec tr" avec la mienne pour éviter le 1 + 3n avec certains sh), mais on lance plus de commandes (1 shell par fichier).