2017-09-06 1 views
0

J'ai le script TCL suivant qui exécute une commande Linux pour formater un fichier.Erreur lors de l'exécution de la commande Linux à l'aide de tcl

 
exec sed -r '2,$s/(.{55})/\1\n\t/g' $formatfileName | sed 's/ $//' > $formatfileName 

je reçois une erreur disant ne peut pas lire « s »: pas de telle variable lors de l'exécution la ligne ci-dessus - Il envisage signe $ dans la commande Linux en tant que variable. J'ai essayé de mettre des accolades {} mais cela n'a pas fonctionné.

Pouvez-vous s'il vous plaît aviser comment utiliser la commande ci-dessus sans erreurs? Merci de votre aide.

Répondre

2

Le problème est que Tcl n'utilise pas de guillemets simples; l'équivalent en Tcl est des accolades (sauf celles qui s'emboîtent correctement). En outre, vous devez écrire dans un fichier différent de celui que vous avez lu ou vous obtenez des conditions de course difficiles entre l'ouverture de plusieurs fichiers en lecture et l'écriture qui effacera votre fichier. (Vous pouvez renommer après.) Quelque chose comme ça devrait fonctionner.

exec sed -r {2,$s/(.{55})/\1\n\t/g} $formatfileName | sed {s/ $//} > $formatfileName.new 
file rename -force $formatfileName.new $formatfileName 

Cela dit, je serais fortement tenté de le faire dans le plus pur Tcl (plus, mais maintenant portable):

set f [open $formatfileName] 
set lines [split [read $f] "\n"] 
close $f 

set f [open $formatfileName "w"] 
foreach line $lines { 
    # First line is special 
    if {[incr LN] == 1} { 
     puts $f [string trimright $line] 
     continue 
    } 
    foreach l [split [regsub {.{55} } $line "&\n\t"] "\n"] { 
     puts $f [string trimright $l] 
    } 
} 
close $f 

Les string trimright s font effectivement ce que la deuxième sed faisait, et le regsub au milieu est reconnaissable similaire à la première sed, bien que j'utilise un split intérieur aussi là-bas afin que le découpage peut être appliqué de manière cohérente.

Ici, il n'y a pas de problème file rename; la lecture précède définitivement l'écriture.

+0

De même, 'sed' peut être transmis plusieurs modèles à appliquer sur la ligne de commande. Vous n'avez pas besoin d'un tuyau. –

+0

Merci beaucoup Donal Fellows, la partie Linux modifiée avec accolades fonctionne comme un charme. Merci pour le code Tcl, il est très proche du code Linux. J'essaie d'apprendre à faire quelques changements pour satisfaire le besoin. – NewCoder

+0

Merci Brad Lanam, ne le savais pas. – NewCoder