2012-06-26 5 views
1

Я хочу, чтобы превратить это (Mitarbeiter.csv):Преобразование файлов с помощью регулярных выражений шаблон в СЭД

Max;Mustermann;02.03.1964;501;GL;Prokurist 
Monika;Mueller;02.02.1972;500;Sek;Chefsekretaerin 
Michael;Maier;06.07.1985;617;Aquise;- 

в этом (заголовок-content.html):

<tr><td>Max</td><td>Mustermann</td><td>501</td></tr> 
<tr><td>Monika</td><td>Mueller</td><td>500</td></tr> 
<tr><td>Michael</td><td>Maier</td><td>617</td></tr> 

с помощью СЭД

Я пробовал:

sed 's#^\([^\]+\);\([^\]+\);[^\]+;\([^\]+\);.*$#<tr><td>\2</td><td>\1</td><td>\3</td></tr>\n#g' <Mitarbeiter.csv >header-content.html 

но т шляпа ничего не делает. Выход такой же, как у Mitarbeiter.csv

+0

должна ли ваша команда СЭД, не хватает, это выход? –

+0

naah, была просто ошибкой форматирования, исправлена. –

ответ

1

Несколько пунктов,

  1. вам нужен -r переключатель для расширенных шаблонов регулярных выражений
  2. Sed жадный, и даже -r не поддерживает не жадные соответствия
  3. Флаг g является special get flag, вы, вероятно, не хотят этого

Так что ваша команда должна быть:

sed -r 's#^([^\;]+);([^\;]+);[^\;]+;([^\;]+);.*$#<tr><td>\1</td><td>\2</td><td>\3</td></tr>#' <Mitarbeiter.csv> header-content.html 

Обратите внимание, что ваши элементы не могут иметь точку с запятой в них, так как это разделитель полей. Если вы являетесь истинным CSV-файлом, это не сработает, так как он не будет игнорировать скелет с точкой с запятой, либо завернутый в кавычки, либо с помощью escape-символа.

+0

Спасибо, ваше решение отлично работало. «g» is FLAG для глобального соответствия, как описано здесь: http://ss64.com/bash/sed.html –

+1

Флаг 'g' действительно для «глобальной» подстановки, но вам все равно это не нужно, поскольку ваше регулярное выражение привязано к началу области поиска. Существует только один «**'^'**». – ghoti

+0

@Frozen_byte hmm, документы grymoire отключены. –

1

Почему вы хотите использовать sed?

awk '{print "<tr><td>"$1"</td><td>"$2"</td><td>"$4"</td></tr>} 
    ' IFS=';' Mitarbeiter.csv > header-content.html 
+0

К сожалению, мне нужно использовать SED, мне не разрешено использовать awk; ( –

2

awk может быть немного лучше подходит к тому, что вы пытаетесь сделать:

awk -F\; '{printf "<tr><td>%s</td><td>%s</td><td>%s</td></tr>\n",$1,$2,$4}' 
+0

К сожалению, мне нужно использовать SED, мне не разрешено использовать awk; ( –

2
sed -r -ne 's:^([^;]+);([^;]+);[^;]+;([^;]+);.*:<tr><td>\1</td><td>\2</td><td>\3</td></tr>:p' 

Или, если вы используете OSX или более старую версию FreeBSD или NetBSD, замените -r с -E использовать расширенные регулярные выражения.

Если вы хотите, чтобы пропустить с помощью ERE портативность (т.е. вы используете Solaris или HP/UX или сконвертировано), регулярное выражение может быть:

^\([^;][^;]*\);\([^;][^;]*\);[^;]*;\([^;][^;]*\);.* 

Обратите внимание, что эти оба требуют по крайней мере 1 символов на поле. Если полям разрешено быть пустым ... ну, обновите свой вопрос, прежде чем мы больше потратим больше времени на вещи, которые могут не понадобиться. :-)

+0

Спасибо, ваше решение сработало. Также я не думаю, что параметры -ne (и p flag) необходимы. –

+1

Рад, что это сработало! Разница с -n (и флагом p) заключается в том, что с ними неверно отформатированные входные строки не будут переданы на ваш вывод. Если вы можете ГАРАНТИРОВАТЬ, что ваш входной файл не будет иметь комментариев или заголовков или плохого форматирования, вы можете пропустить «защитную сетку». – ghoti

1

Если вы настаиваете на использовании СЭД, вы можете попробовать:

$ p='\([^;]*\);' 
$ sed "[email protected]$p$p$p$p.*@<tr><td>\1</td><td>\2</td><td>\4</td></tr>@" \ 
     Mitarbeiter.csv > header-content.html 
Смежные вопросы