Comment trouver et remplacer une chaîne sans utiliser la commande Sed?

Comme nous le savons tous, sed est très efficace pour trouver et remplacer une chaîne, par exemple trouver « a » et remplacez-le par « b »: sed "s/a/b/g".

Est-il possible de faire cela avec une autre commande ou un script shell au lieu de sed?

Ceci est pour un système Linux recadré pour la télévision qui na pas la commande sed. Je dois donc utiliser dautres commandes ou scripts au lieu de sed "s/a/b/g". –

Commentaires

  • En fait, cest juste substitution basée sur une expression régulière. Tout outil ou langage capable de gérer une telle chose pourra faire de même, mais avec différentes syntaxes: $var=~s/a/b/g, gsub(/a/,"b",var), var.gsub(/a/,'b'), var.replace(/a/g,'b'), preg_replace("/a/","b",$var), regsub -all a b $var. En plus de cela, de nombreux outils et langages peuvent également remplacer une chaîne de texte brut. Votre question est donc assez large.
  • Pourquoi? Quel problème essayez-vous de résoudre?
  • Un système Linux recadré pour la télévision na pas de commande sed. Je dois donc utiliser une autre commande ou un autre script au lieu de sed ‘ s / a / b / g ‘.

Réponse

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

Exemples

Disons que jai cet exemple de données, dans un fichier 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

Ce qui précède Les exemples peuvent également modifier directement les fichiers. Lexemple Perl est trivial. Ajoutez simplement le commutateur -i.

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

Pour awk « un peu moins 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ù se trouve le fichier redirigé vers celui-ci via ceci:

$ { ... } < data.txt 

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

Commentaires

  • Merci pour votre réponse et je vais lessayer le prochain jour ouvrable.Mais je ne suis pas sûr si cela fonctionne parce que certaines commandes nexistent peut-être pas dans un système de télévision Linux recadré, comme ‘ sed ‘. Donc je veux toujours utiliser commande ‘ recherchez ‘, ‘ grep ‘ et ainsi de suite pour le résoudre.
  • @binghenzq – Jai ‘ ajouté des exemples qui modifient le fichier en ligne.
  • -1 Je déconseille rarement mais dans ce cas, le point de la question semblait être une méthode plus simple plutôt quune autre plus / également complexe et probablement aussi dépendante. Si la question portait uniquement sur les alternatives pour une installation complète de la machine * nix, je donnerais probablement +1 à cette bonne réponse.
  • @MichaelDurrant – Je viens dajouter ces modifications en ligne élaborées, car lOP les a demandées . De plus, lOP a défini lexigence de PAS en utilisant sed pas I. Sed est loutil approprié pour faire des substitutions comme celle-ci, et il ‘ s demander manifestement de mieux comprendre les rôles de ces outils, donc montrer à quelquun ces choses bien que mauvaises, est extrêmement instructif pour leur montrer pourquoi. Trop souvent, les personnes au courant disent simplement  » don ‘ t faire  » sans expliquer pourquoi, donc je le suis. Mais merci davoir au moins laissé un commentaire expliquant pourquoi vous DV.
  • Bien sûr, jai trouvé que cétait une excellente réponse à tous les autres égards. ouais je déteste -1 sans explication.

Réponse

Lalternative classique pour les substitutions dune seule lettre est la tr commande qui devrait être disponible sur à peu près nimporte quel système:

$ echo "foobar" | tr a b foobbr 

tr est meilleur que sed pour cela en fait depuis lutilisation de sed (sans parler de perl ou awk) pour les substitutions dune seule lettre, cest comme utiliser une masse pour tuer une mouche.

grep nest pas conçu pour cela, il ne modifie pas son entrée, il ne fait que la rechercher.

Vous pouvez également utiliser les capacités de substitution de certains shells. 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 expliquiez exactement quel problème vous essayez de résoudre.

Commentaires

  • Existe-t-il une option pour ignorer la casse dans ${foo//a/b}?
  • @ AlikElzin-kilaka Jai ‘ jai peur ne pas. Vous ‘ devrez utiliser quelque chose de plus sophistiqué comme, par exemple: echo "$foo" | sed 's/a/b/i ou donner une classe de caractères: echo ${foo//[aA]/b}.

Réponse

Vous pouvez utiliser loutil POSIX ex:

ex a.txt <<eof %s/Sunday/Monday/g xit eof 

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html

Commentaires

  • merci beaucoup. juste pour ajouter, -c flag est dexécuter la commande quand lédition commence (puisque ex est un éditeur) et -s flag est soit le mode script désactivant le feedback, soit comme certains aiment le dire slient-mode. ref pour plus dinformations: ex-vi.sourceforge.net/ex.html

Réponse

Si vous « travaillez avec un fichier plutôt quun flux, vous pouvez utiliser léditeur de texte standard, ed:

printf "%s\n" ",s/a/b/g" w q | ed file.txt 

Cela devrait être disponible sur nimporte quel * nix. La virgule dans ",s/a/b/g" indique ed pour travailler sur chaque ligne (vous pouvez également utiliser %, qui sera plus familier si vous « êtes habitué à vim), et le reste de celui-ci est une recherche et un remplacement standard. w lui dit décrire (enregistrer) le fichier, q lui dit de quitter.

Notez que, contrairement à sed « s -i (et des options similaires dans dautres outils), cela modifie le fichier sur place plutôt que de tricher avec des fichiers temporaires.

Je ne le fais pas. « Je ne pense pas quil » est possible de faire fonctionner cela avec des flux, mais je ne sais pas vraiment grand-chose sur ed et je ne serais pas surpris quil ait réellement cette capacité (la philosophie unix étant ce quelle est).

Réponse

Utilisation de lancêtre (dans laquelle -s signifie silencieux (silencieux) et la virgule avant les commandes signifie exécuter sur toutes les lignes):

Il suffit dimprimer sur STDOUT :

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

remplacement sur place:

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

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *