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?

Avinash Raj
źródło
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.

unxnut
źródło
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.

terdon
źródło
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
@terdon co powiesz na to echo "aa\nbb" | awk '{gsub(/\\n/,"\n");}1;'?
Avinash Raj
@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.

mikeserv
źródło
0

Z gnu sednastępujących działa również:

gsed -n -e 'H;${x;s/\\n/\n/g;p;}'
Dirk Hoffmann
źródło
-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"
jpmuc
źródło
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