Използване на sed за разделяне на низ с разделител

Имам низ в следния формат:

string1:string2:string3:string4:string5

Опитвам се да използвам sed, за да разделя низа на : и да отпечатам всеки подниз на нов ред. Ето какво правя:

cat ~/Desktop/myfile.txt | sed s/:/\\n/

Това отпечатва:

string1
string2:string3:string4:string5

Как мога да го накарам да се раздели на всеки разделител?


person hax0r_n_code    schedule 14.08.2013    source източник
comment
Можете да помислите за tr : '\n' <~/Desktop/myfile.txt. Тъй като sed може да отваря файлове доста щастливо, не е необходимо да използвате cat във вашия пример от въпроса.   -  person Jonathan Leffler    schedule 14.08.2013


Отговори (6)


За да разделите низ с разделител с GNU sed, казвате:

sed 's/delimiter/\n/g'     # GNU sed

Например, за да разделите с помощта на : като разделител:

$ sed 's/:/\n/g' <<< "he:llo:you"
he
llo
you

Или с не-GNU sed:

$ sed $'s/:/\\\n/g' <<< "he:llo:you"
he
llo
you

В този конкретен случай сте пропуснали g след замяната. Следователно, това се прави само веднъж. Вижте:

$ echo "string1:string2:string3:string4:string5" | sed s/:/\\n/g
string1
string2
string3
string4
string5

g означава global и означава, че заместването трябва да се извърши глобално, тоест за всяко събитие. Виж, че по подразбиране е 1 и ако сложиш примерно 2 се прави 2 пъти и т.н.

Всички заедно, във вашия случай ще трябва да използвате:

sed 's/:/\\n/g' ~/Desktop/myfile.txt

Имайте предвид, че можете директно да използвате синтаксиса sed ... file, вместо ненужни канали: cat file | sed.

person fedorqui 'SO stop harming'    schedule 14.08.2013
comment
Мамка му! Бях толкова близо. Какво прави g? И ще приема отговора ви веднага щом мога. Благодаря! - person hax0r_n_code; 14.08.2013
comment
Това означава global и означава, че заместването трябва да се извърши globally, тоест за всяко събитие. Виж, че по подразбиране е 1 и ако сложиш примерно 2 се прави 2 пъти и т.н. - person fedorqui 'SO stop harming'; 14.08.2013
comment
Това не работи в не-GNU sed. Каноничният/преносим начин да направите, да речем, вашия последен пример би бил sed $'s/:/\\\n/g' file.txt, разчитайки на цитиране на bash формат, за да интерпретирате ANSI обратната наклонена черта. - person ghoti; 06.01.2019
comment
@ghoti благодаря, актуализирах и с този подход. В бъдеще не се колебайте да актуализирате публикациите, за да ги направите по-правилни, всички се учим от това! - person fedorqui 'SO stop harming'; 07.01.2019

Използването на \n в sed не е преносимо. Преносимият начин да правите каквото искате с sed е:

sed 's/:/\
/g' ~/Desktop/myfile.txt

но в действителност това така или иначе не е работа за sed, това е работата, за която tr е създаден:

tr ':' '
' < ~/Desktop/myfile.txt
person Ed Morton    schedule 14.08.2013
comment
На iTerm, на MacOS, крайният знак може да бъде направен на входа с помощта на alt+enter. Удобен трик за разделяне на $PATH променлива между другото. - person GabLeRoux; 31.07.2017

Използвайки просто tr :

$ tr ':' $'\n' <<< string1:string2:string3:string4:string5
string1
string2
string3
string4
string5

Ако наистина имате нужда от sed :

$ sed 's/:/\n/g' <<< string1:string2:string3:string4:string5
string1
string2
string3
string4
string5
person Gilles Quenot    schedule 14.08.2013
comment
Хареса решението с помощта на tr. Просто и удобно. Благодаря - person Darshan Dorai; 04.12.2016

Това може да работи за вас (GNU sed):

sed 'y/:/\n/' file

или може би:

sed y/:/$"\n"/ file
person potong    schedule 14.08.2013

Това трябва да го направи:

cat ~/Desktop/myfile.txt | sed s/:/\\n/g
person Jiminion    schedule 14.08.2013

Ако използвате gnu sed, можете да използвате \x0A за нов ред:

sed 's/:/\x0A/g' ~/Desktop/myfile.txt
person anubhava    schedule 14.08.2013
comment
Не е задължително. Средите Win32 ще използват различен символ за нов ред и последно проверих Cygwin използва gnu sed. - person ghoti; 06.01.2019