2015-12-26 3 views
2

У меня есть следующие строки в файлеSplit линия с несколькими разделителями в Unix

id=1234,name=abcd,age=76 
id=4323,name=asdasd,age=43 

за исключением того, что реальный файл имеет гораздо больше tag=value полей на каждой строке. Я хочу конечный результат быть как

id,name,age 
1234,abcd,76 
4323,asdasd,43 

Хочу все значения, прежде чем (слева их) = выйти отделенными с , в качестве первой строки и все значения после (справа) из = для каждой строки

Есть ли способ сделать это с помощью awk или sed? Пожалуйста, дайте мне знать, требуется ли для цикла цикл for.

Я работаю над Solaris 10; местным sed является не GNU sed (так нет -r вариант, а не -E).

+0

Пожалуйста, укажите ваш СЭД версия. Спасибо –

+0

Какую версию Solaris вы используете? – Cyrus

+0

Это Solaris 10 – Akshay

ответ

0
FILE=yourfile.txt 

# first line (header) 
cat "$FILE" | head -n 1 | sed -r "s/=[^,]+//g" 

# other lines (data) 
cat "$FILE" | sed -r "s/[^,]+=//g" 
+0

Привет, Томас, это было быстро. Спасибо. Sed sed -r выходит, чтобы сказать, незаконный вариант. Есть ли альтернатива? – Akshay

+0

Интересно, работает для меня здесь. Но я нахожусь в Linux, поэтому вполне возможно, что ваш sed - это другая версия. –

+0

Это правда. Я нахожусь в офисе, и эта вещь передо мной - Solaris. – Akshay

0
sed -r '1 s/^/id,name,age\n/;s/id=|name=|age=//g' my_file 

редактировать: или использовать

sed '1 s/^/id,name,age\n/;s/id=\|name=\|age=//g' 

выход

id,name,age 
1234,abcd,76 ...(n number of fields) 
4323,asdasd,43... 
+0

sed -r не работает на моей Solaris – Akshay

+0

попробуйте «sed --help» и посмотрите, какие аргументы имеют описание «использовать расширенные регулярные выражения в скрипте». ... затем используйте этот аргумент ... – repzero

+0

-e -f и -n поддерживаются только .Is есть альтернатива – Akshay

2
$ cat tst.awk 
BEGIN { FS="[,=]"; OFS="," } 
NR==1 { 
    for (i=1;i<NF;i+=2) { 
     printf "%s%s", $i, (i<(NF-1) ? OFS : ORS) 
    } 
} 
{ 
    for (i=2;i<=NF;i+=2) { 
     printf "%s%s", $i, (i<NF ? OFS : ORS) 
    } 
} 

$ awk -f tst.awk file 
id,name,age 
1234,abcd,76 
4323,asdasd,43 

Предполагая, что они на самом деле не существует в вашем входе, я удалил ... s и т.д. которые загромождали ваш пример до runnin g выше. Если этот материал действительно существует на вашем входе, уточните, как вы хотите, чтобы текст «(n число полей)» был идентифицирован и удален (строка соответствует? Position on line? Something else?).

EDIT: так как вам нравится краткость cat|head|sed; cat|sed подхода, публикуемую в другой ответ, вот эквивалент в AWK:

$ awk 'NR==1{h=$0;gsub(/=[^,]+/,"",h);print h} {gsub(/[^,]+=/,"")} 1' file 
id,name,age 
1234,abcd,76 
4323,asdasd,43 
+1

.... Я написал почти точно такие же коды ...... +1 – Kent

+0

Wow. Вообще-то, у меня был псевдо-код для вышеупомянутого, но я не мог понять его в синтаксисе. Как бы то ни было, я бы выбрал решение, упомянутое Томасом и Киром, поскольку оно просто занимает одну строчку. Спасибо за тонну. – Akshay

+0

Нет, опубликованное решение cat + head + sed не принимает только одну строку, и оно использует UUOC, и оно использует несколько инструментов + трубок, если это нужно сделать, и требуется 2 прохода файла, и это не сработает, если ваш вход был исходящий из потока вместо файла. Удачи! –

0

Следующая просто сочетает в себе лучшее из ответов СЭД на основе до сих пор, показывая вам, может иметь ваш торт и съесть его тоже. Если ваш sed не поддерживает опцию -r, возможно, что -E будет делать трюк; все еще не удается, можно заменить R + РР *, где R является [^]

sed -r '1s/=[^,]+//g; s/[^,]+=//g' 

(То есть, портативный колдовство будет:

sed "1s/=[^,][^,]*//g; s/[^,][^,]*=//g" 

)

+0

Не могли бы вы поместить здесь все альтернативы? Я использую solaris и -r и -E не поддерживается. – Akshay

Смежные вопросы