Mam polecenie zamiany sed, które chciałbym być kompatybilne zarówno z BSD, sed
jak i GNU sed
. Rozszerzone wyrażenia regularne nie stanowią problemu, ponieważ nie potrzebuję ich w tym przypadku. Moim głównym problemem jest różnica w sposobie, w jaki oba sed
interpretują sekwencje specjalne znaków w ciągach zastępujących . Mój ciąg zastępujący zawiera tabulatory i znaki nowej linii i chciałbym, aby były one widoczne w ciągach poleceń dla ułatwienia konserwacji, jednak BSD sed
nie interpretuje sekwencji specjalnych i GNU sed
tak . Jaki jest właściwy sposób instruowania, sed
aby interpretować te sekwencje specjalne w BSD? Następujące dwa fragmenty są uosobieniem mojego problemu:
GNU ANTYLOPA sed
echo ABC | sed 's/B/\n\tB\n'
yeilds
A
B
C
BSD sed
echo ABC | sed 's/B\n\tB\n'
daje
AntBnC
Oczywiście, \n
i \t
nie są interpretowane przez BSD jako sekwencje specjalnesed
A teraz moje pytanie. Według strony BSD sed
:
Aby określić znak nowego wiersza w ciągu zastępującym, poprzedź go odwrotnym ukośnikiem.
Czy to oznacza, że musiałbym poprzedzić dosłowny znak nowej linii odwrotnym ukośnikiem? Jaki jest właściwy sposób instruowania, sed
aby interpretować sekwencje specjalne jak \n
w tekście zastępczym?
sed
. W końcu prawdopodobnie będzie sensowne użycie awk. Co sądzisz o interpretacji cytowanej przeze mnie strony podręcznika BSD?Odpowiedzi:
Jeśli chcesz pisać przenośne skrypty, powinieneś trzymać się funkcji w standardzie POSIX (aka Single Unix aka Open Group Base Specification). Numer 7, znany również jako POSIX-1.2008, jest najnowszy, ale wiele systemów jeszcze go nie przyjęło. Wydanie 6, znane również jako POSIX-1.2001, jest zasadniczo dostarczane przez wszystkie współczesne jednorożce.
W sed , znaczenie sekwencje jak
\t
i\n
nie jest przenośne, chyba że w regex ,\n
stoi za linią. W tekście zastępującyms
polecenie\n
nie jest przenośny, ale można użyć sekwencji odwrotnego ukośnika-nowa linia, aby zastąpić nową linię.Przenośnym sposobem generowania znaku tabulacji (lub dowolnego innego znaku wyrażonego ósemkowo) jest
tr
. Przechowuj znak w zmiennej powłoki i podstaw tę zmienną we fragmencie sed.Zauważ ponownie, że znaki nowej linii muszą być wyrażane inaczej w wyrażeniach regularnych i
s
tekstach zastępczych.Zamiast tego możesz użyć awk . Umożliwia ucieczki w odwrotnym ukośniku, w tym ósemkowe
\ooo
, w każdym dosłownym ciągu znaków.źródło
Możesz użyć
$'...'
cudzysłowu, aby zinterpretować znaki ucieczki przed przekazaniem ciągused
.Ze strony podręcznika użytkownika bash:
źródło
Odpowiedź została udzielona w przypadku przepełnienia stosu:
/programming/1421478/how-do-i-use-a-new-line-replacement-in-a-bsd-sed
To prawie dokładnie to, co powiedział jw013.
Aby wstawić literalny tabulator, wpisz ctrl+ VTab.
źródło