2016-10-27 2 views
0

У меня есть файл с записями, разделенными |. Существует несколько разрывов строк, когда часть первой строки перемещается во вторую строку. Если я вычислил количество | в определенной строке, он должен быть согласованным во всем. Как определить, какая строка имеет разрыв строки как таковой и добавить две строки в одну, так как число '|' в каждой строке согласовано во всем?Линейные перерывы в файле Unix

Файл что-то, как показано ниже:

DeptID|EmpFName|EmpLName|Salary 
Engg|Sam|Le 
wis|1000 
Engg|Smith|Davis|2000 
HR|Denis 
|Lillie|1500 
HR|Danny|Borr 
inson|3000 
IT|David|Letterman|2000 
IT|John|Newman|3000 

, тогда как я хочу, чтобы вычислить число «|» в каждой строке.

В этом случае каждая строка должна иметь 3 '|' каждый, но из-за разрывов строк, что это не так,

Мой последний требуемый выход

DeptID|EmpFName|EmpLName|Salary 
Engg|Sam|Lewis|1000 
Engg|Smith|Davis|2000 
HR|Denis|Lillie|1500 
HR|Danny|Borrinson|3000 
IT|David|Letterman|2000 
IT|John|Newman|3000 
+1

Пожалуйста, разместите некоторые данные примера и ожидаемый результат. –

+0

ответ в дублированном вопросе работает, за исключением добавленного пространства ... поэтому необходима какая-то модификация, и я не знаю, является ли изменение тривиальным (не ссылаясь на разделитель полей, но дополнительное пространство) – Sundeep

+1

Не можете ли вы использовать 'sed 'для замены новой строки на пустую строку? Я имею в виду, что сначала вы используете «ловушку», чтобы знать количество символов '|', а если оно меньше 3, вы удаляете новую строку пустой строкой. – Dominique

ответ

0

Один в AWK:

$ cat foo.awk 
BEGIN { FS=OFS="|" } # set separators 
NR==1 { nf=NF }  # expect the field count to be correct on header record 
NF<nf {    # if NF less than on header record 
    while (NF<nf) { # and while NF < less than on header record 
     b=$0   # buffer too short record 
     getline  # read next record 
     $0 = b $0  # catenate buffer and fresh record 
    } 
} 1     # output 

Выполнить это:

$ awk -f foo.awk foo 
DeptID|EmpFName|EmpLName|Salary 
Engg|Sam|Lewis|1000 
Engg|Smith|Davis|2000 
HR|Denis|Lillie|1500 
HR|Danny|Borrinson|3000 
IT|David|Letterman|2000 
IT|John|Newman|3000 

не проверяет, является ли запись растет слишком долго.

0

Учитывая, что при макс раскол на две строки, как указано на ОП в вопросе, sed может быть используется для простого решения

$ cat ip.txt 
DeptID|EmpFName|EmpLName|Salary 
Engg|Sam|Le 
wis|1000 
Engg|Smith|Davis|2000 
HR|Denis 
|Lillie|1500 
HR|Danny|Borr 
inson|3000 
IT|David|Letterman|2000 
IT|John|Newman|3000 

$ sed '/.*|.*|.*|/! {N; s/\n//}' ip.txt 
DeptID|EmpFName|EmpLName|Salary 
Engg|Sam|Lewis|1000 
Engg|Smith|Davis|2000 
HR|Denis|Lillie|1500 
HR|Danny|Borrinson|3000 
IT|David|Letterman|2000 
IT|John|Newman|3000 
  • /.*|.*|.*|/!, если строка не содержит три |
    • {N; s/\n//} получить следующую строку и удалить первую \n


Используйте группировку и квантор указать номер вместо

sed '/\(.*|\)\{3\}/! {N; s/\n//}' ip.txt 

с расширенными регулярными выражениями, -E или -r

sed -E '/(.*\|){3}/! {N; s/\n//}' ip.txt 
+0

Есть ли способ сохранить значение 3 в переменной и использовать переменную в приведенной выше команде. Я пытаюсь использовать нижеследующее, но оно не принимает значение переменной. $ cat ip.TXT Deptme | EmpLName | Зарплата Engg | Сэм | Le И | 1000 Engg | Смит | Дэвис | 2000 HR | Денис | Лилли | 1500 HR | Danny | Borr инсон | 3000 IT | David | Леттерман | 2000 IT | John | Newman | 3000 $ var = $ (sed 's/[^ |] // g' ip.txt | awk '{print length}' | head -1) $ echo $ var $ sed '/\(.*|\)\{${var}\}/! {N; s/\ n //} 'ip.txt sed: -e выражение # 1, char 19: Недопустимый контент \ {\} – Dgstah

+0

использовать 'sed' /\(.*|\)\{$var\}/ ! {N; s/\ n //} "ip.txt' – Sundeep

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