Comment find et replace la string sans utiliser la command Sed?

Comme nous le soaps tous, sed est très efficace pour find et replace des strings, par exemple find 'a' et le replace par 'b': sed 's/a/b/g' .

Est-il possible de le faire avec d'autres commands ou scripts shell au lieu de sed ?

Ceci est pour les systèmes linux recadrés pour les téléviseurs qui n'ont pas la command sed . Je dois donc utiliser d'autres commands ou scripts au lieu de sed 's/a/b/g'. – sed 's/a/b/g'. –

Oui, il existe plusieurs façons de le faire. Vous pouvez également utiliser awk , perl ou bash pour effectuer ces activités. En général, sed est probablement l'outil le plus approprié pour effectuer ces types de tâches.

Exemples

Dire que j'ai ces données d'exemple, dans un file data.txt :

 foo bar 12,300.50 foo bar 2,300.50 abc xyz 1,22,300.50 

awk

 $ awk '{gsub("foo", "foofoofoo", $0); print}' data.txt foofoofoo bar 12,300.50 foofoofoo bar 2,300.50 abc xyz 1,22,300.50 

Perl

 $ perl -pe "s/foo/foofoofoo/g" data.txt foofoofoo bar 12,300.50 foofoofoo bar 2,300.50 abc xyz 1,22,300.50 

Modification en ligne

Les exemples ci-dessus peuvent modifier directement les files aussi. L'exemple Perl est sortingvial. Il suffit d'append le commutateur -i .

 $ perl -pie "s/foo/foofoofoo/g" data.txt 

Pour awk c'est un peu less direct mais tout aussi efficace:

 $ { rm data.txt && awk '{gsub("foo", "foofoofoo", $0); print}' > data.txt; } < data.txt 

Cette méthode crée un sous-shell avec les accolades {…} `où le file y est redirigé via:

 $ { ... } < data.txt 

Une fois que le file a été redirigé dans le sous-shell, il est supprimé, puis awk est exécuté sur le contenu du file qui a été lu dans les sous-shell STDIN. Ce contenu est ensuite traité par awk et renvoyé au même nom de file que nous venons de supprimer, le remplaçant efficacement.

L'alternative classique pour les substitutions de lettre simple est la command tr qui devrait être disponible sur à peu près n'importe quel système:

 $ echo "foobar" | tr ab foobbr 

tr est mieux que sed pour cela en fait, puisque l'utilisation de sed (et encore less de perl ou awk ) pour des substitutions de lettres simples est comme l'utilisation d'un marteau pour tuer une mouche.

grep n'est pas conçu pour cela, il ne modifie pas son input, il ne fait que le parcourir.

Alternativement, vous pouvez utiliser les capacités de substitution de certains obus. Ici en utilisant la syntaxe ksh , zsh ou bash :

 $ foo="foobar" $ echo "${foo//a/b}" foobbr 

Nous pourrions vous donner des réponses plus spécifiques si vous avez expliqué exactement le problème que vous essayez de résoudre.

Si vous travaillez avec un file plutôt qu'avec un stream, vous pouvez utiliser l'éditeur de text standard, ed :

 printf '%s\n' ',s/a/b/g' wq | ed file.txt 

Cela devrait être disponible sur n'importe quel * nix. La virgule dans ',s/a/b/g' indique de travailler sur chaque ligne (vous pouvez aussi utiliser % , qui sera plus familier si vous êtes habitué à vim), et le rest est une search standard et replace. w dit d'écrire (sauvegarder) le file, q dit de sortir.

Notez que, à la différence de l'option -i de sed (et des options similaires dans d'autres outils), cela modifie le file sur place plutôt que de sortingcher avec des files temporaires.

Je ne pense pas qu'il soit possible de travailler avec des stream, mais je ne sais pas grand-chose à propos de ed et je ne serais pas surpris si elle a réellement cette capacité (la philosophie Unix étant ce qu'elle est).

Vous pouvez utiliser Vim en mode Ex:

 ex -sc '%s/a/b/g|x' file 
  1. % select toutes les lignes

  2. substitut

  3. g global replace

  4. x sauvegarder et fermer

L'utilisation de la command ancestor ed (dans laquelle -s signifie quiet (silence) et la virgule avant les commands signifie s'exécuter sur toutes les lignes):

Il suffit d'imprimer sur STDOUT :

 ed -s file <<! ,s/a/b/g ,p q ! 

replace sur place:

 ed -s file <<! ,s/a/b/g w q !