J'ai une situation où je veux qu'un script bash remplace une ligne entière dans un fichier. Le numéro de ligne est toujours le même, ce qui peut être une variable codée en dur.
Je n'essaye pas de remplacer une sous-chaîne dans cette ligne, je veux juste remplacer cette ligne entièrement par une nouvelle ligne.
Existe-t-il des méthodes bash pour faire cela (ou quelque chose de simple qui peut être jeté dans un script .sh).
sed: -e expression #1, char 26: unknown option to ``s'
et ma ligne est:sed -i '7s/.*/<param-value>http://localhost:8080/ASDF/services/REWS.REWSHttpSoap12Endpoint/</param-value>/' $TCE_SVN_HOME\trunk\tce\EWC\WebContent\WEB-INF\web.xml
. Une idée?/
dans le texte de remplacement serait interprété comme la barre oblique de fermeture de las
commande à moins que escape (\/
). La chose la plus simple à faire, cependant, est de choisir un caractère différent et inutilisé comme délimiteur. Par exemplesed -i '7s{.*}{<param-value>http://...}' $TCE_SVN_HOME/trunk...
,.s
détermine le délimiteur. Donc pour changer votre commande pour utiliser par exemple le#
ce serait comme ceci:sed -i '7s#.*#<param-value>http://localhost:8080/ASDF/services/REWS.REWSHttpSoap12Endpoint/</param-value>#'
-e
if-i
; ainsi, la commande correcte devient:sed -e 'Ns/.*/replacement-line/' -i '' file.txt
J'ai en fait utilisé ce script pour remplacer une ligne de code dans le fichier cron sur les serveurs UNIX de notre société il y a quelque temps. Nous l'avons exécuté comme un script shell normal et n'avons eu aucun problème:
Cela ne se fait pas par numéro de ligne, mais vous pouvez facilement passer à un système basé sur le numéro de ligne en mettant le numéro de ligne avant le
s/
et en plaçant un caractère générique à la place dethe_original_line
.la source
sed -e "s/.../.../" /dir/file > /dir/temp_file
sed -e "s/.../.../" /dir/file > /dir/file
Supposons que vous souhaitiez remplacer la ligne 4 par le texte "différent". Vous pouvez utiliser AWK comme ceci:
AWK considère l'entrée comme étant des "enregistrements" divisés en "champs". Par défaut, une ligne correspond à un enregistrement.
NR
est le nombre d'enregistrements vus.$0
représente l'enregistrement complet actuel (while$1
est le premier champ de l'enregistrement et ainsi de suite; par défaut, les champs sont des mots de la ligne).Ainsi, si le numéro de ligne actuel est 4, imprimez la chaîne "différent" mais sinon imprimez la ligne inchangée.
Dans AWK, le code de programme inclus dans
{ }
s'exécute une fois sur chaque enregistrement d'entrée.Vous devez citer le programme AWK entre guillemets simples pour empêcher le shell d'essayer d'interpréter des choses comme le
$0
.EDIT: Un programme AWK plus court et plus élégant de @chepner dans les commentaires ci-dessous:
Uniquement pour l'enregistrement (c'est-à-dire la ligne) numéro 4, remplacez l'ensemble de l'enregistrement par la chaîne «différent». Ensuite, pour chaque enregistrement d'entrée, imprimez l'enregistrement.
De toute évidence, mes compétences AWK sont rouillées! Merci, @chepner.
EDIT: et voir aussi une version encore plus courte de @Dennis Williamson:
Comment cela fonctionne est expliqué dans les commentaires: le
1
évalue toujours vrai, donc le bloc de code associé s'exécute toujours. Mais il n'y a pas de bloc de code associé, ce qui signifie qu'AWK effectue son action par défaut consistant simplement à imprimer la ligne entière. AWK est conçu pour autoriser des programmes laconiques comme celui-ci.la source
awk 'NR==4 {$0="different"} { print }' input_file.txt
.awk 'NR==4 {$0="different"}1' input_file.txt
1
? (Remarque: je l'ai testé et cela fonctionne vraiment! Je ne comprends tout simplement pas comment.)Compte tenu de ce fichier de test (test.txt)
la commande suivante remplacera la première ligne par "texte de nouvelle ligne"
Résultat:
Plus d'informations peuvent être trouvées ici
http://www.thegeekstuff.com/2009/11/unix-sed-tutorial-append-insert-replace-and-count-file-lines/
la source
sed '1 cnewline text' test.txt
le ferait aussi.dans bash, remplacez N, M par les numéros de ligne et xxx yyy par ce que vous voulez
ÉDITER
En fait, dans cette solution, il y a quelques problèmes, avec les caractères "\ 0" "\ t" et "\"
"\ t", peut être résolu en mettant IFS = avant lecture: "\", en fin de ligne avec -r
mais pour "\ 0", la variable est tronquée, il n'y a pas de solution en bash pur: Assignez une chaîne contenant un caractère nul (\ 0) à une variable en bash Mais dans un fichier texte normal, il n'y a pas de caractère nul \ 0
perl serait un meilleur choix
la source
la source
Excellente réponse de Chepner. Cela fonctionne pour moi dans bash Shell.
here
index
- Line nonewLine
- nouvelle chaîne de ligne que nous voulons remplacer.De même, le code ci-dessous est utilisé pour lire une ligne particulière dans le fichier. Cela n'affectera pas le fichier réel.
ici
!d
- supprimera les lignes autres que la ligne no.$index
Nous obtiendrons donc la sortie sous forme de chaîne de ligne de no$index
dans le fichier.la source
${newline}
?Sur Mac, j'ai utilisé
la source
Vous pouvez même passer des paramètres à la commande sed:
test.sh
orignial output.dat:
L'exécution de ./test.sh donne le nouveau output.dat
la source
line=5; sed -i "${line}s/.*/replaced by '$i'!/" output.dat