Verwenden Sie diesen sed-Befehl, um Folgendes zu erreichen:
sed '/^#/,/^\$/{/^#/!{/^\$/!d}}' file.txt
Mac-Benutzer müssen (um extra characters at the end of d command
Fehler zu vermeiden ) vor den schließenden Klammern Semikolons hinzufügen
sed '/^#/,/^\$/{/^#/!{/^\$/!d;};}' file.txt
AUSGABE
$ description 1
blah blah
$ description 2
blah blah
blah blah
Erläuterung:
/^#/,/^\$/
wird den gesamten Text zwischen Zeilen, die mit beginnen #
, und Zeilen, die mit beginnen , abgleichen $
. ^
wird für den Zeilenanfang verwendet. $
ist ein Sonderzeichen und muss daher entkommen.
/^#/!
bedeutet folgendes tun, wenn der Zeilenanfang nicht ist #
/^$/!
bedeutet folgendes tun, wenn der Zeilenanfang nicht ist $
d
bedeutet löschen
Insgesamt werden also zuerst alle Zeilen von ^#
bis ^\$
dann von diesen übereinstimmenden Zeilen abgeglichen, um Linien zu finden, die nicht übereinstimmen ^#
und nicht übereinstimmen, ^\$
und sie mit zu löschen d
.
extra characters at the end of d command
Fehler zu vermeiden , müssen Sie vor den schließenden Klammern Semikolons hinzufügensed '/^#/,/^\$/{/^#/!{/^\$/!d;};}' file.txt
sed '/^#/,/^\$/d' file
$ cat test 1 start 2 end 3 $ sed -n '1,/start/p;/end/,$p' test 1 start end 3 $ sed '/start/,/end/d' test 1 3
quelle
'1,/start/p;/end/,$p'
ich habe meinen Workflow komplett durcheinander gebracht, da ich mich auf diese Arbeit verlassen habe. Bei mir funktioniert das überhaupt nicht.sed '/PATTERN-1/,/PATTERN-2/{//!d}' input.txt
Wenn Sie im Allgemeinen eine Datei mit dem Inhalt des Formulars abcde haben , wobei Abschnitt a vor Muster b steht , Abschnitt c vor Muster d steht , dann Abschnitt e folgt und Sie die folgenden
sed
Befehle anwenden , erhalten Sie die folgenden Ergebnisse.In dieser Demonstration wird die Ausgabe durch dargestellt
=> abcde
, wobei die Buchstaben zeigen, welche Abschnitte in der Ausgabe enthalten wären. Somitae
zeigt eine Ausgabe nur der Abschnitte a und e ,ace
wären die Abschnitte a , c und e usw.Beachten Sie, dass wenn
b
oderd
in der Ausgabe erscheinen, dies die Muster sind, die erscheinen (dh sie werden so behandelt, als wären sie Abschnitte in der Ausgabe).Verwechseln Sie das
/d/
Muster auch nicht mit dem Befehld
. Der Befehl ist bei diesen Demonstrationen immer am Ende. Das Muster liegt immer zwischen dem//
.sed -n -e '/b/,/d/!p' abcde
=> aesed -n -e '/b/,/d/p' abcde
=> bcdsed -n -e '/b/,/d/{//!p}' abcde
=> csed -n -e '/b/,/d/{//p}' abcde
=> bdsed -e '/b/,/d/!d' abcde
=> bcdsed -e '/b/,/d/d' abcde
=> aesed -e '/b/,/d/{//!d}' abcde
=> abdesed -e '/b/,/d/{//d}' abcde
=> Assquelle
Ein anderer Ansatz mit sed:
sed '/^#/,/^\$/{//!d;};' file
/^#/,/^\$/
: von der Zeile beginnend mit#
bis zur nächsten Zeile beginnend mit$
//!d
: Löschen Sie alle Zeilen mit Ausnahme derjenigen, die den Adressmustern entsprechenquelle
sed '/^#/,/^\$/d;' file
.Ich habe so etwas vor langer Zeit gemacht und es war so etwas wie:
sed -n -e "1,/# ID 1/ p" -e "/\$ description 1/,$ p"
Welches ist so etwas wie:
-n
Alle Ausgaben unterdrücken-e "1,/# ID 1/ p"
Ausführen von der ersten Zeile bis zu Ihrem Muster und p (Drucken)-e "/\$ description 1/,$ p"
Ausführen vom zweiten Muster bis zum Ende und p (Drucken).Ich könnte mich irren, wenn einige der Saiten entkommen, also überprüfen Sie es bitte noch einmal.
quelle
Im folgenden Beispiel werden Zeilen zwischen "if" und "end if" entfernt .
Alle Dateien werden gescannt und Linien zwischen den beiden übereinstimmenden Mustern werden entfernt (einschließlich dieser).
IFS=' ' PATTERN_1="^if" PATTERN_2="end if" # Search for the 1st pattern in all files under the current directory. GREP_RESULTS=(`grep -nRi "$PATTERN_1" .`) # Go through each result for line in "${GREP_RESULTS[@]}"; do # Save the file and line number where the match was found. FILE=${line%%:*} START_LINE=`echo "$line" | cut -f2 -d:` # Search on the same file for a match of the 2nd pattern. The search # starts from the line where the 1st pattern was matched. GREP_RESULT=(`tail -n +${START_LINE} $FILE | grep -in "$PATTERN_2" | head -n1`) END_LINE="$(( $START_LINE + `echo "$GREP_RESULT" | cut -f1 -d:` - 1 ))" # Remove lines between first and second match from file sed -e "${START_LINE},${END_LINE}d;" $FILE > $FILE done
quelle