/ / SED - usuwanie ciągu, po którym następuje LineFeed (n) - linux, unix, sed, awk, vi

SED - usuwanie ciągu, po którym następuje LineFeed (n) - linux, unix, sed, awk, vi

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 № 1

W 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