Remplacer la ligne entière contenant une chaîne en utilisant Sed

j'ai un fichier texte qui a une ligne particulière quelque chose comme

sometext sometext sometext TEXT_TO_BE_REPLACED sometext sometext sometext

je dois remplacer toute la ligne ci-dessus par

This line is removed by the admin.

le mot clé de recherche est TEXT_TO_BE_REPLACED

j'ai besoin d'écrire un script shell pour cela. Comment réaliser cela en utilisant sed ?

226
demandé sur Jens 2012-06-28 16:55:26

10 réponses

vous pouvez utiliser la commande change pour remplacer la ligne entière, et le drapeau -i pour effectuer les changements en place. Par exemple, en utilisant GNU sed:

sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo
369
répondu Todd A. Jacobs 2018-07-31 04:21:56

vous devez utiliser wildards ( .* ) avant et après pour remplacer la ligne entière:

sed 's/.*TEXT_TO_BE_REPLACED.*/This line is removed by the admin./'
111
répondu Thor 2012-06-28 13:08:26

Les accepté de répondre ne fonctionne pas pour moi pour plusieurs raisons:

  • ma version de sed n'aime pas -i avec une extension zéro longueur
  • la syntaxe de la commande c\ est étrange et je n'ai pas pu la faire fonctionner
  • Je n'avais pas réalisé que certains de mes problèmes venaient de slashes sans issue

voici donc la solution que j'ai trouvée et qui devrait fonctionner pour la plupart des cas:

function escape_slashes {
    sed 's/\//\\//g' 
}

function change_line {
    local OLD_LINE_PATTERN=; shift
    local NEW_LINE=; shift
    local FILE=

    local NEW=$(echo "${NEW_LINE}" | escape_slashes)
    sed -i .bak '/'"${OLD_LINE_PATTERN}"'/s/.*/'"${NEW}"'/' "${FILE}"
    mv "${FILE}.bak" /tmp/
}

ainsi l'utilisation de l'échantillon pour résoudre le problème posé:

change_line "TEXT_TO_BE_REPLACED" "This line is removed by the admin." yourFile
16
répondu skensell 2015-02-01 11:13:47

La Réponse ci-dessus:

sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo

fonctionne très bien si la chaîne/ligne de remplacement n'est pas une variable.

le problème est que sur Redhat 5 Le \ après le c échappe au $ . Un double \ ne fonctionnait pas non plus (du moins sur Redhat 5).

par hit and trial, j'ai découvert que le \ après le c est redondant si votre chaîne/ligne de remplacement est seulement une seule ligne. Donc, je n'ai pas utilisé \ après le c , utilisé une variable comme une ligne de remplacement simple et il était de la joie.

le code ressemblerait à quelque chose comme:

sed -i "/TEXT_TO_BE_REPLACED/c $REPLACEMENT_TEXT_STRING" /tmp/foo

Remarque l'utilisation de guillemets au lieu de guillemets simples.

8
répondu user4256255 2016-03-24 08:50:04

dans mon makefile j'utilise ceci:

@sed -i '/.*Revision:.*/c\'"`svn info -R main.cpp | awk '/^Rev/'`"'' README.md

PS: NE PAS oubliez pas que l'-je change réellement le texte dans le fichier... donc, si le modèle que vous avez défini comme "Révision" va changer, vous aurez également changer le motif à remplacer.

exemple de sortie:

Abc-projet écrit par John Doe

révision: 1190

donc si vous définissez le motif " révision: 1190 "ce n'est évidemment pas la même chose que vous les avez définis comme" révision: "seulement...

1
répondu Martin Pfeffer 2015-12-10 01:56:15
bash-4.1$ new_db_host="DB_HOSTNAME=good replaced with 122.334.567.90"
bash-4.1$ 
bash-4.1$ sed -i "/DB_HOST/c $new_db_host" test4sed
vim test4sed
'
'
'
DB_HOSTNAME=good replaced with 122.334.567.90
'

il fonctionne très bien

1
répondu nkl 2017-03-10 09:08:54

toutes les réponses fournies jusqu'à présent supposent que vous savez quelque chose sur le texte à remplacer qui a du sens, puisque c'est ce que l'OP a demandé. Je fournis une réponse qui suppose que vous ne savez rien sur le texte à remplacer et qu'il peut y avoir une ligne séparée dans le fichier avec le même contenu ou similaire que vous ne voulez pas être remplacé. De plus, je suppose que vous connaissez le numéro de ligne de la ligne à remplacer.

les exemples suivants démontrer la suppression ou la modification du texte par des numéros de ligne spécifiques:

# replace line 17 with some replacement text and make changes in file (-i switch)
# the "-i" switch indicates that we want to change the file. Leave it out if you'd
#   just like to see the potential changes output to the terminal window.
# "17s" indicates that we're searching line 17
# ".*" indicates that we want to change the text of the entire line
# "REPLACEMENT-TEXT" is the new text to put on that line
# "PATH-TO-FILE" tells us what file to operate on
sed -i '17s/.*/REPLACEMENT-TEXT/' PATH-TO-FILE

# replace specific text on line 3
sed -i '3s/TEXT-TO-REPLACE/REPLACEMENT-TEXT/'
1
répondu b_laoshi 2017-08-14 07:11:16
cat find_replace | while read pattern replacement ; do
sed -i "/${pattern}/c ${replacement}" file    
done 

fichier find_replace contient 2 colonnes, c1 avec motif à apparier, c2 avec remplacement, la boucle sed remplace chaque ligne contenant l'un des motifs de la variable 1

1
répondu sjordi 2017-08-31 10:44:33

il est aussi similaire à celui ci-dessus..

sed 's/[A-Za-z0-9]*TEXT_TO_BE_REPLACED.[A-Za-z0-9]*/This line is removed by the admin./'
0
répondu Annapureddy Hari 2013-05-30 09:15:46

j'utilise très souvent regex pour extraire des données à partir de fichiers que je viens d'utiliser pour remplacer la citation littérale \" par // rien: -)

cat file.csv | egrep '^\"([0-9]{1,3}\.[0-9]{1,3}\.)' | sed  s/\"//g  | cut -d, -f1 > list.txt
0
répondu staM 2015-11-08 22:33:20