2016-04-06 4 views
0

Ich habe eine Datei, die diese Zeilen hat:

s17 line linewidth 1.0 
s18 line linewidth 1.0 
. 
. 
. 
s28 line linewidth 1.0 

ich durch diese Zeilen ersetzen möchten:

s17 line linewidth 2.0 
s18 line linewidth 2.0 
. 
. 
. 
s28 line linewidth 2.0 

ich habe diesen Code in bash geschrieben:

#!/bin/bash 
for VARIABLE in {17..28} 
do 
    sed 's/s${VARIABLE} line linewidth 1\.0/s${VARIABLE} line linewidth 2\.0/g' ./band-structure-calcite.agr 
done 

Dann habe ich den Code ausführen, indem bash change.sh > changed.txt machen, aber die Datei changed.txt nicht cont ain diesen Änderungen.

Ich würde mich sehr freuen, wenn Sie mir helfen und erklären mir die Syntax des Codes Antworten, wie ich lerne bash

+3

Einfache Anführungszeichen interpolieren keine Variablen, doppelte Anführungszeichen tun dies. – choroba

+0

Das Ausführen von 'sed' N-mal ist ineffizient und wird Ihnen viele doppelte Ausgabezeilen geben (N Kopien jeder Zeile mit * einem * jeder Kopie wurden entsprechend modifiziert). Wenn Sie nur "1.0" auf "2.0" in Zeilen ändern möchten, die mit diesen Zahlen übereinstimmen (und vermutlich nicht mit anderen), gibt es dafür bessere Möglichkeiten. –

+0

@choroba: Ich habe das Skript geändert in: 'sed 's/s $ {VARIABLE} Zeilenbreite 1 \ .0/s $ {VARIABLE} Zeilenbreite 2 \ .0/g" ./band-structure-calcite. agr "und es funktioniert nicht –

Antwort

2

Anstatt sed läuft mehrmals, einen sed-Skript in der Schleife erzeugen und es einmal ausgeführt:

for n in {17..28} ; do 
    echo "s/s$n line linewidth 1\.0/s$n line linewidth 2.0/g" 
done | sed -f- ./band-structure-calcite.agr > changed.txt 
+0

Vielen Dank, es hat funktioniert, aber ich muss den Code verstehen ... die Zeile: 'echo "s/s $ n Zeilenbreite 1 \ .0/s $ n Zeilenbreite 2.0/g" ' Ausdruck:' s/s17 Zeilenbreite 1 \ .0/s17 Zeilenbreite 2 \ .0/g' ' s/s18 Linienbreite 1 \ .0/s18 Linienbreite 2 \ .0/g' '.' ' .' '.' Dann beenden Sie die Schleife mit' Done' gefolgt von '| sed -f- Dateiname'. Nun, was macht '| sed -f- Dateiname bedeutet? Nochmals vielen Dank :) –

+0

@DavidC .: Es ruft sed, das die Ausgabe der Schleife als Skript interpretiert. – choroba

+0

Ok, vielen Dank! –

1

einen regulären Ausdruck mit Ihren Zahlen Fabrikat:

allnr="" 
for nr in {17..28} 
do 
    allnr+="${nr}|" 
done 
# Debug: echo "allnr=${allnr%|}" 
sed -r 's/s('"${allnr%|}"') line linewidth 1\.0/s\1 line linewidth 2.0/g' ./band-structure-calcite.agr 
+0

Danke für deine Antwort :) –

1

die Schleife Ersetzen mit regulären Ausdrücken in der Adresse par t des sed-Befehl:

'/^s\(\(1[7-9]\)\|\(2[0-8]\)\)\s/ s/1\.0$/2.0/' ./band-structure-calcite.agr 

Der reguläre Ausdruck (/^s\(\(1[7-9]\)\|\(2[0-8]\)\)\s/) entspricht Linien mit s17 beginnen, s18, ... oder s28, gefolgt von einem Leerzeichen oder Tab und sed gilt folgende s/1\.0$/2.0/ Befehl nur für diejenigen, Linien. Andere Zeilen durchlaufen unverändert. Die ganze Datei wird genau einmal durchgelesen, und die Ausgabe enthält eine Ausgabezeile pro Eingabezeile, anders als Ihr Original.

+0

Danke für Ihre Antwort! +1! –