2010-03-07 2 views
1

Comment puis-je utiliser sed pour remplacer cette lignele remplacement d'un chemin avec sed

char * path_list_[1] = { "/some/random/path" }; 

avec cette ligne

char * path_list_[2] = { "lib/foo", "lib/bar" }; 

dans un fichier nommé source.c

Notes:
* Le chemin est vraiment aléatoire.
* Votre solution ne devrait changer cette ligne que dans la source.c
* Je ne suis intéressé que par un sed oneliner.

Vous pouvez utiliser cette regex Python comme point de départ:

text = re.sub('static const char \* path_list_\[1\] = \{ "[^"]*" \};', 
    'static const char * path_list_[2] = { "lib/sun", "lib/matlab" };', text) 
+4

S'il n'y a que 1 ligne dans 1 fichier alors il est beaucoup plus efficace pour remplacer le 'path_list_' manuellement que d'attendre 7 jours pour la meilleure réponse. :) – kennytm

Répondre

1

Basé sur le Python vous regex donné:

echo 'char * path_list_[1] = { "/some/random/path" };' | \ 
    sed -E -e 's/char \* path_list_\[1\] = \{ "[^"]*" \};/char * path_list_[2] = { "lib\/sun", "lib\/matlab" };/' 

sorties

char * path_list_[2] = { "lib/sun", "lib/matlab" }; 

ou alternativement

echo 'static const char * path_list_[1] = { "/some/random/path" };' | \ 
    sed -E -e 's/static const char \* path_list_\[1\] = \{ "[^"]*" \};/static const char * path_list_[2] = { "lib\/sun", "lib\/matlab" };/' 

sorties

static const char * path_list_[2] = { "lib/sun", "lib/matlab" }; 

(Ceci est fait en utilisant le type FreeBSD Sed inclus dans Mac OS X.)

1

Essayez ceci:

sed -e 's/=\s*{\s*"[^"]*"\s*};/= { "lib\/foo", "lib\/bar"};/' source.c | sed -e 's/path_list_\[1\]/path_list_[2]/' 
+0

@compie: Oui, sed supporte la négation dans la classe char.J'ai mis à jour ma réponse. – codaddict

+0

Cette solution correspond à trop de lignes. Le fichier d'entrée contient beaucoup d'autres codes C. – compie

+1

@compie: pouvez-vous s'il vous plaît me montrer quelques lignes qui sont remplacées faussement. – codaddict

1

D'abord, trouver un personnage qui n'apparaîtra dans votre chemin ou votre remplacement (en général # est une bonne première approximation, mais ...).

Puis:

sed 's#_.1. = {[^}]*}#_[2] = { "your/first", "and/your/second" }#' 

Notez que le premier caractère après l's est votre séparateur, il n'y a pas besoin pour qu'il soit /, il est juste traditionnellement « le personnage que je ne aurai pas besoin ».

EDIT: On dirait que sed ne comprend pas + comme "un ou plusieurs". Utilisez plutôt * (zéro ou plus).

+0

Cela ne fonctionne pas: echo 'char * path_list_ [1] = {"/ some/random/path};' | sed 's #_. 1. = {[^}] +} #_ [2] = {"votre/premier", "et/votre/seconde"} #' Rien n'est remplacé – compie

+0

Sed ne comprend pas ' + ', mais vous devez écrire' \ + 'au lieu de' + ', ou fournir la clé' -r' – ZyX

1
$ cat file 
aaaa 
char * path_list_[1] = { "/some/random/path" }; 
zzzz 

$ sed '/char/[email protected]\]@2]@;[email protected]{.*}.*[email protected]{\"lib\/foo", "lib\/bar"}@' file 
aaaa 
char * path_list_[2] = {"lib/foo", "lib/bar"} 
zzzz 
+0

C'est un sed oneliner ... l'autre texte est juste une démonstration – Broam

+0

Cela fonctionne, mais une ligne comme struct = {"value"}; est également remplacé – compie

+0

Ensuite, vous devriez montrer plus d'exemples de chaînes et le format que vous avez besoin d'analyser Dans votre exemple de texte, vous n'avez pas 'struct'. – ghostdog74

1

En supposant que vous souhaitez remplacer les variables de chaîne nommée path_list_, et seulement celles-ci.

sed '/path_list_/[email protected]\]@2]@; /path_list_.*\[.*{/[email protected]\".*\"@\"lib\/foo", "lib\/bar"@' 

Ceci remplace seulement les 2 premières lignes de l'entrée suivante.

char * path_list_[1] = { "/some/random/path" }; 
char * path_list_[1] = {"/some/random/path"}; 
char * not_replaced[1] = { "/some/random/path" }; 
char * not_replaced[1] = {"/some/random/path"}; 
char * path_list_ = {"/some/random/path"}; 
path_list_[1] = "/some/random/path"; 
0
sed -e '[email protected] \* path_list_\[1\] = { "[^"]*" };@char * path_list_[2] = { "lib/foo", "lib/bar" };@g' 
0
sed -re 's/^(char \* path_list_\[)1(\] = \{ ")[^"]*(" \})\W*$/\12\2\/lib\/foo", "\/lib\/bar\3/' source.c