Czy występuje problem ze znakiem sed i nową linią?
Mam plik test.txt z następującą zawartością
aaaaa
bbbbb
ccccc
ddddd
Następujące nie działa:
sed -r -i 's/\n/,/g' test.txt
Wiem, że mogę tr
z tego skorzystać, ale moje pytanie brzmi: dlaczego wydaje się to niemożliwe z sedem.
Jeśli jest to efekt uboczny przetwarzania pliku linia po linii, byłbym zainteresowany, dlaczego tak się dzieje. Myślę, że grep
usuwa nowe linie. Czy sed robi to samo?
tr
dodałby znak końca,
i wyprowadziłby niezakończoną linię. Najlepiej użyćpaste
zamiast tego:paste -sd , test.txt
Odpowiedzi:
Z GNU
sed
i pod warunkiemPOSIXLY_CORRECT
nie ma go w środowisku (dla wprowadzania jednowierszowego):Od https://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n :
:a
N
$!ba
($!
oznacza to, aby nie robić tego w ostatnim wierszu (ponieważ powinna istnieć jedna końcowa nowa linia)).źródło
ba: Event not found
sed
polecenie z tymi dokładnymi opcjami? W jakimtest.txt
pliku? Z którą wersjąsed
(trysed --version
)?!
. Co ciekawe, to wciąż nie działało dla mnie i ostatecznie musiałem podwójnie uciec z!
mojego.csh
skryptu. W tej chwili tak naprawdę nie mam problemu, ale czy wiesz, dlaczego tak się dzieje? Dla mniesed :a;N;$\\!ba;s/\n/ /g'
Działa to z GNU
sed
:-z
jest uwzględnione od 4.2.2NB.
-z
zmienia separator na znaki puste (\0
). Jeśli dane wejściowe nie zawierają żadnych znaków zerowych, całe dane wejściowe są traktowane jako pojedynczy wiersz. Może to wynikać z jego ograniczeń .Aby uniknąć zastąpienia nowego wiersza ostatniego wiersza, możesz go zmienić z powrotem:
(Która jest
sed
ponownie składnią GNU , ale to nie ma znaczenia, ponieważ całość jest tylko GNU)źródło
Ze strony internetowej Oracle:
Zasadniczo oznacza to, że ponieważ sed czyta wiersz po wierszu, znak nowej linii nie jest dopasowany.
Rozwiązanie z https://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n to:
lub, w wersji przenośnej (bez
;
łączenia po etykietach znaczników skoku)Wyjaśnienie, jak to działa, znajduje się na tej stronie.
źródło
sed
, jeśli POSIXLY_CORRECT znajduje się w środowisku, a wejście ma tylko jedną linię, nie będzie żadnych danych wyjściowych.sed
zawsze usuwa końcowy\n
ewline tuż przed zapełnieniem przestrzeni wzorców, a następnie dołącza jeden przed wypisaniem wyników skryptu.\n
Ewline można było w strukturze przestrzeni na różne sposoby - ale nigdy, jeśli nie jest wynikiem zmiany. Jest to ważne -\n
ewline wsed
przestrzeni wzorów zawsze odzwierciedla zmianę i nigdy nie występuje w strumieniu wejściowym.\n
ewline to jedyny ogranicznik, na którysed
der może liczyć przy nieznanych danych wejściowych.Jeśli chcesz zastąpić wszystkie
\n
ewline przecinkami, a plik nie jest zbyt duży, możesz:To dodaje każdą linię wejściową do
h
starej spacji - z wyjątkiem pierwszej, która zamiast tego zastępujeh
starą spację - po\n
znaku ewline. Następnied
usuwa każdy wiersz nie$!
ostatni z wyniku. W ostatnim wierszuH
stare i wzorce sąx
zmieniane, a wszystkie\n
znaki ewline sąy///
tłumaczone na przecinki.W przypadku dużych plików taka sytuacja z
sed
pewnością spowoduje problemy - bufor na granicach linii, który można łatwo przepełnić tego rodzaju działaniami.źródło
Alternatywnie możesz użyć nieco prostszej składni:
... tylko zmieniam kolejność sekwencji.
źródło
s
polecenie dla każdego wiersza wejściowego na przestrzeni wzorów, która jest coraz większa.Jest tu bardzo ładna magia sed . I kilka dobrych uwag dotyczących przepełnienia przestrzeni wzorów. Uwielbiam używać sed, nawet jeśli nie jest to najprostszy sposób, ponieważ jest tak kompaktowy i mocny. Ma to jednak swoje ograniczenia, a dla dużych ilości danych przestrzeń wzorców musiałaby być mahoosive.
GNU mówi to:
Nie mam wiele do dodania, ale chciałbym skierować cię w stronę mojego przewodnika po sed . To jest świetne. http://www.grymoire.com/Unix/Sed.html
a oto moje rozwiązanie:
dobrze to działa
źródło
Powiedzmy, że chcesz zastąpić znaki nowej linii
\n
. Chciałem to zrobić, więc oto co zrobiłem:Oto, co robi: dla wszystkich linii z wyjątkiem ostatniej , dołącz
\n
. Następnie usuń nowe linie za pomocątr
.źródło
-r
jest dostępny tylko w GNUsed
, a nie BSD.