Zamień \ n nową linią w przenośny sed


23

Jestem tak pomylony z niezliczonymi opcjami GNU sed, POSIX sedi BSD sed. Jak zastąpić literał \nznakiem nowej linii, używając tych trzech sedtypów?


Mają wiele różnych rzeczy, którą część chcesz wiedzieć?
cuonglm

@Gnouc myślę, że teraz jest jasne.
Avinash Raj

1
Czy spojrzałeś na to pytanie ?
groxxda

2
Co chcesz się wydarzyć na podstawie danych wejściowych takich jak foo\\nbarlub foo\\\nbar?
Gilles 'SO - przestań być zły'

proste, foo \\ w następnym wierszu będzie to bar.
Avinash Raj

Odpowiedzi:


30
sed 's/\\n/\
/g'

Zwróć uwagę na odwrotny ukośnik tuż przed naciśnięciem klawisza return w ciągu zastępującym.


czy to działa na wszystkie rodzaje sedów?
Avinash Raj

Wierzę, że powinno; Testowałem tylko na systemie Linux, używając wersji GNU.
unxnut

11
@AvinashRaj. To POSIX i działało z oryginalnym sedpoleceniem w Uniksie v7 w 1979 roku. Jedynym miejscem, w którym to może nie działać, byłyby uproszczone implementacje inne niż POSIX, sedtakie jak niektóre zredukowane oparte na busyboksie. To nie zadziała w csh, ale jest to problem csh.
Stéphane Chazelas

Ponieważ \\njest używany w części wyszukiwania, dlaczego nie użyć \nw zamianie? pierwsze wydaje się sugerować, że drugie istnieje. to znaczy. dlaczego nie to$ echo '1\n2'|sed 's/\\n/\n/g'

W tym przypadku \njest dosłowny, co oznacza, że ​​pojawia się jako dwa znaki: przerywnik, po którym następuje n, a nie jako pojedynczy znak nowej linii. Stąd dwa ukośniki odwrotne za uczynienie ukośnika dosłownym, a następnien
unxnut

9

Ponieważ masz już przenośną sedodpowiedź, wspomnę tylko, że sedrzadko jest to najlepsze narzędzie, jeśli chcesz w jakiś sposób manipulować nowymi liniami. Perl jest prawie tak samo przenośny, jak sedzainstalowany domyślnie na większości systemów * nix i może sobie z tym poradzić bardzo łatwo:

printf '%s\n' 'aa\nbb' | perl -pe 's/\\n/\n/g'

Innym bardzo przenośnym wyborem jest awk:

printf '%s\n' 'aa\nbb' | awk  '{gsub("\\\\n","\n")};1'

W systemie Solaris pamiętaj o użyciu standardowego awk w / usr / xpg4 / bin, ten w / bin jest historycznym i nie powinien być używany w nowych skryptach.


Powiedziałbym, że awkma podobne problemy z przenośnością (czy moja awkzwykła stara awk, nawkczy gawk?). W rzeczywistości brakuje wersji w moich pudełkach Solaris gsub(). Mój głos tutaj dotyczy Perla ( perl -nlawe '...'przybliżone automatyczne zachowanie awk).
arielCo

2
@arielCo: Aby zapewnić awkprzenośność, trzymaj się wersji awkzgodnej z POSIX i używaj tylko tych funkcji i wszystko powinno być w porządku. W systemie Solaris znajdziesz jeden jako /usr/xpg4/bin/awk.
Skrutinizer


@arielCo, awk jest bardziej przenośny niż perl. Moje drugie podejście do awk, które nie wykorzystuje, gsub()powinno działać wszędzie. Nawet busybox ma awk.
terdon

1
gsub () to POSIX (gsub, został dodany w SVR3.1, POSIX awk jest oparty na SVR4 z kilkoma dodatkami, zobacz podręcznik gawk, aby uzyskać więcej informacji), gensub () to rozszerzenie GNU. Pierwotny awk nadal występujący jako / bin / awk w systemie Solaris, nie obsługiwał gsub (), ale nie obsługiwał także wieloznakowego FS.
Stéphane Chazelas

1

Jeśli Holdspace jest pusty, możesz także:

sed '/\\n/G;s/\\n\(.*\)\(.\)/\2\1/;P;D'

... ale odpowiedź uxnut jest już szybsza i prostsza, więc możesz wziąć ją tak, jak chcesz.

Inna obca możliwość:

INPUT | sed -n l | while read v ; do printf "${v%?}" ; done

Ale uwaga ^, która tłumaczy wszystkie standardowe znaki \ukośnika odwrotnego w stylu C - takie jak \backspace i \return oraz \00ósemki i co chcesz.



-2

Potrzebujesz rozwiązania w sed, a to już podano poniżej. Chciałem jednak dodać kolejną możliwość, że IMHO jest po prostu łatwiejsze i szybsze,

tr -d "\n"

1
co to robi usunąć wszystkie nowe wiersze z wejścia?
mikeserv

Tak, właśnie to robi
jpmuc

5
ale dlaczego? co to w ogóle ma wspólnego z pytaniem?
mikeserv

1
To po prostu usuwa „\ n”, gdy pytanie pyta, jak zastąpić ciąg „\ n” rzeczywistymi znakami nowej linii.
spuder
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.