Mam poniższy plik wyjściowy w poniższym formacie z skryptu powłoki

data  text1

data1 text2

data3 text4,text5,text6,text7,text8,text9,text10,text12,text11,text13

data4 text53

data23 text45,text65,text98,text65`

Chcesz zmienić format wyjścia dalej, jak poniżej, aby być bardziej czytelnym

data   text1

data1  text2

data3  text4

data3  text5

data3  text6

data3  text7

data3  text8

data3  text9

data3  text10

data4  text53

data23 text45

data23 text65

data23 text98

data23 text65

Proszę doradzić, jak osiągnąć to samo za pomocą awk / sed? Próbowałem przyglądać się do poleceń awk, ale nie dostajaj żadnych wskazówek jako takich, każda pomoc byłaby doceniona dzięki

1
shirop 2 czerwiec 2018, 02:21

4 odpowiedzi

Najlepsza odpowiedź
$ awk -F'[ ,]+' '{for (i=2;i<=NF;i++) print $1, $i ORS}' file
data text1

data1 text2

data3 text4

data3 text5

data3 text6

data3 text7

data3 text8

data3 text9

data3 text10

data3 text12

data3 text11

data3 text13

data4 text53

data23 text45

data23 text65

data23 text98

data23 text65
1
Ed Morton 2 czerwiec 2018, 14:51

Możesz użyć czegoś takiego:

output | gawk '{split($2, a, /,/); for (i=1; i <= length(a); i++) {printf "%s %s\n\n", $1, a[i]}}'

Gdzie output to wyjście generowane przez skrypt.

Alternatywnie, biegasz w ten sposób:

gawk '{split($2, a, /,/); for (i=1; i <= length(a); i++) {printf "%s %s\n\n", $1, a[i]}}' output_file

Edytowane, aby naprawić błędy wskazywane przez @ed Morton i wymienione awk za pomocą gawk od length(array) jest rozszerzeniem GNU.

1
accdias 2 czerwiec 2018, 18:01

Inny przy użyciu gsub do ,:

$ awk '{gsub(/,/, ORS ORS $1 OFS )}1' file
...
data3 text4

data3 text5

data3 text6
...

Jednak jeśli $1 ma na przykład &, będzie w nim kłopoty, ponieważ zostanie zastąpiony mecz:

$ cat file
data& text4,text5,text6
$ awk '{gsub(/,/, ORS ORS $1 OFS )}1' file
data& text4

data, text5

data, text6

Napraw to za pomocą innego gsub:

$ awk '{gsub(/,/, ORS ORS $1 OFS ); gsub(/,/,"\\&")}1' file
data& text4

data& text5

data& text6
0
James Brown 2 czerwiec 2018, 06:15

Możesz złożyć linię jeden raz

sed -r 's/([^ ]* +)([^,]*),(.*)/\1\2\n\n\1\3/g' file

Powtarzanie potrzebuje markera skoku

sed -r ': a;s/([^ ]* +)([^,]*),(.*)/\1\2\n\n\1\3/g; t a' file
0
Walter A 2 czerwiec 2018, 13:46