Nie mogę znaleźć odpowiedniego wyrażenia sed, aby usunąć słowo, po którym następuje powrót linii (n)
Plik testowy to:
line1n
line2n
line3markn
line4n
line5n
i chcę usunąć wszystkie wystąpienia markn pozostawiając, w tym przypadku:
line1n
line2n
line3line4n
line5n
przeszukali i mogą używać:
sed "s/n//g" test.file to remove ALL n"s
ale
sed "s/markn//g" test.file does not work
Dziwne, s / markn // g wydaje się działać poprawnie w vi w trybie interaktywnym.
Każda pomoc bardzo doceniona! Chciałbym zrozumieć, jak to zrobić za pomocą SED, jeśli to możliwe, ponieważ jestem pewien, że jest to możliwe !! Jeśli jednak można to zrobić w inny sposób, to ja też jestem szczęśliwy, dopóki jest w linii poleceń, ponieważ musi działać na wielu plikach.
Wielkie dzięki.
Odpowiedzi:
6 dla odpowiedzi № 1W przypadku rzeczywistych kanałów, użyj:
sed -e ":a; /mark$/ { N; s/markn//; ba; }"
Wszystkie linie kończące się znakiem są łączone z następnym, a teraz środkowe n jest usuwane.
Jeśli istnieje dosłowny ciąg n
na końcu linii musisz uciec tak jak
\n
.
4 dla odpowiedzi nr 2
To powinno wystarczyć:
sed -i ":a;N;$!ba;s/markn//g" file
Wyjaśnienie:
; command separator within sed
:a a label, like in C/C++
N appends the next line to the pattern space
$!ba repeats the N command for all lines but the last line
sed postępuje w ten sposób. odczytuje standardowe wejście do przestrzeni wzorca, wykonuje sekwencję poleceń edycyjnych w przestrzeni wzorca, a następnie zapisuje przestrzeń wzorców do STDOUT.
Kiedy robisz coś takiego
sed -i "s/markn//" file
linie są kopiowane do przestrzeni wzorca jeden po drugim.
:a;N;$!ba
dołącza każdą linię do przestrzeni wzoru.
Następnie przestrzeń wzoru może być przetwarzana w jednym przebiegu, usuwając wszystkie markn
, g
opcja globalna jest tutaj ważna, ponieważ pyta sed, aby nie zatrzymywał się przy pierwszym pasującym wzorcu.
2 dla odpowiedzi nr 3
widziałem awk
tag, więc idziemy.
Gdyby n
jest „zwrotem wiersza”, awk może dołączyć linię kończącą się „znakiem” w następnym wierszu.
$> awk "/mark$/ { sub(/mark$/,""); getline t; print $0 t; next }; 1" ./text
line1
line2
line3line4
line5
1 dla odpowiedzi nr 4
Jeśli możesz użyć awk, możesz to zrobić
awk "
/mark$/ {sub(/mark$/, ""); hold = hold $0; next}
{print hold $0; hold = ""}
END {if (hold) print hold}
"
1 dla odpowiedzi nr 5
jest już wiele odpowiedzi, sed i awk.
Dodaję kolejny, awk, po prostu pokaż, że awk może to zrobić w krótszym poleceniu:
awk "gsub(/mark$/,""){printf $0;next;}1" input
test:
kent$ echo "line1
line2
line3mark
line4
line5"|awk "gsub(/mark$/,""){printf $0;next;}1"
wydajność:
line1
line2
line3line4
line5
Nie wiem, czy to naprawdę jest OP.
0 dla odpowiedzi № 6
Użyj następującego polecenia
sed -e "{:q;N;s/markn//g;t q}" test.file
0 dla odpowiedzi № 7
To może działać dla Ciebie:
sed -e "1{h;d};H;${x;s/markn//g;p};d" test.file
0 dla odpowiedzi № 8
awk "{sub(/line4/,"line3line4")}!/mark/" file
line1n
line2n
line3line4n
line5n