bash найти и заменить ввод запятой перед заданным шаблоном

У меня есть большой файл CSV, содержащий такие абзацы:

first line1  
second line1  
third line1  
fourth line1  
first line2  
second line2  
third line2  
fourth line2

После обработки хотелось бы перевести на это:

first line1,second line1,third line1,fourth line1  
first line2,second line2,third line2,fourth line2

Примечание: первая строка, вторая строка и т. д. содержат специальные символы, например . , " :

Я думаю, что вариант может заключаться в том, чтобы найти «второе» слово из второй строки 1 и заменить «ввод» перед ним запятой, таким образом, вторая строка 1 будет справа от первой строки 1.

Как я могу это сделать?

Действительно, очень возможно, что приведенный выше пример не является реальными АКТУАЛЬНЫМИ данными, вот они:

137822118,user,User,192.168.100.20,2016-07-25 23:19:05 DST,iScript,iScript send MML command,B12345-BXL_ABCD_BD,Succeeded,"NE Name:B12345-BXL_ABCD_BD  
MML Command:LST DEVIP:OPONEMS=""user"", IPOFEMSWS=""192.168.100.20"";  
MML Result:Successful.  
",2016-07-25 23:19:05 DST  
137821234,user,User,192.168.100.21,2016-07-25 23:19:05 DST,iScript,iScript send MML command,B12345-BXL_ASDF_BD,Succeeded,"NE Name:B12345-BXL_ASDF_BD  
MML Command:LST DEVIP:OPONEMS=""user"", IPOFEMSWS=""192.168.100.21"";  
MML Result:Successful.  
",2016-07-25 22:18:05 DST

Файл CSV содержит много таких абзацев.

Вывод должен быть (один абзац в одной строке):

137822118,user,User,192.168.100.20,2016-07-25 23:19:05 DST,iScript,iScript send MML command,B12345-BXL_ABCD_BD,Succeeded,"NE Name:B12345-BXL_ABCD_BD,MML Command:LST DEVIP:OPONEMS=""user"", IPOFEMSWS=""192.168.100.20""; MML Result:Successful.  ",2016-07-25 23:19:05 DST    
137821234,user,User,192.168.100.21,2016-07-25 23:19:05 DST,iScript,iScript send MML command,B12345-BXL_ASDF_BD,Succeeded,"NE Name:B12345-BXL_ASDF_BD,MML Command:LST DEVIP:OPONEMS=""user"", IPOFEMSWS=""192.168.100.21""; MML Result:Successful.  ",2016-07-25 22:18:05 DST

Большое спасибо за твою помощь!

Я пробовал ваши решения, и это почти работает, но это не ожидаемый результат. Кажется, что пример, который я вам привожу, немного отличается от исходного файла из-за формата публикации здесь.

Пожалуйста, найдите ниже настоящий исходный файл CSV (всего несколько строк, так как полный файл содержит более одного миллиона)

https://www.wetransfer.com/downloads/637b36b2148550ad090c22c9e8297a9c20160804081835/48b90b

Извините за недоразумение и еще раз спасибо!


person Bogdan    schedule 03.08.2016    source источник
comment
Всегда ли в наборе 4 строки? Пожалуйста, покажите ФАКТИЧЕСКИЕ данные, чтобы мы могли видеть размещение специальных символов и т. д.   -  person Gary_W    schedule 03.08.2016
comment
Это дубликат stackoverflow.com/q/38731863/1745001, но я не могу закрыть его как дубликат, так как ответ еще не был одобрен или принят.   -  person Ed Morton    schedule 03.08.2016


Ответы (5)


другая альтернатива

$ awk '{ORS=NR%4?",":RS}1' file

сбрасывать разделитель выходных записей каждые четыре строки и печатать.

person karakfa    schedule 03.08.2016

Вы можете использовать для этого paste, например:

$ paste -d, - - - - < file
first line1,second line1,third line1,fourth line1
first line2,second line2,third line2,fourth line2

- означает стандартный ввод, когда вы укажете N из них (N=4 в этом примере), paste сформирует строку из N строк из стандартного ввода.

-d — указать разделитель столбцов, в данном примере — запятую.

person janos    schedule 03.08.2016

попробуй это;

 awk -v patt="first" 'BEGIN{ORS=","}$0 ~ patt {gsub(patt, "\n"patt)}1'  CSVfile
person Mustafa DOGRU    schedule 03.08.2016
comment
Он оставляет конечные запятые. - person James Brown; 03.08.2016

$ awk 'NR==1 {prev=$0; next} {printf "%s", prev; printf "%s", $0~/^[0-9]{9}/ ?"\n":","; prev=$0} END{print prev}' test.in
137822118,user,User,192.168.100.20,2016-07-25 23:19:05 DST,iScript,iScript send MML command,B12345-BXL_ABCD_BD,Succeeded,"NE Name:B12345-BXL_ABCD_BD  ,MML Command:LST DEVIP:OPONEMS=""user"", IPOFEMSWS=""192.168.100.20"";  ,MML Result:Successful.  ,",2016-07-25 23:19:05 DST
137821234,user,User,192.168.100.21,2016-07-25 23:19:05 DST,iScript,iScript send MML command,B12345-BXL_ASDF_BD,Succeeded,"NE Name:B12345-BXL_ASDF_BD  ,MML Command:LST DEVIP:OPONEMS=""user"", IPOFEMSWS=""192.168.100.21"";  ,MML Result:Successful.  ,",2016-07-25 22:18:05 DST

Когда новая запись начинается с набора цифр, пора переходить на новую строку. В следующий раз, пожалуйста, размещайте правильные данные в самом начале.

person James Brown    schedule 03.08.2016

Используя GNU awk для FPAT и не делая никаких предположений о том, сколько строк или полей имеет ваш ввод или какие значения полей встречаются в начале/конце записей:

$ cat decsv.awk
BEGIN { FPAT = "([^,]*)|(\"[^\"]+\")"; OFS="," }
{
    # create strings that cannot exist in the input to map escaped quotes to
    gsub(/a/,"aA")
    gsub(/\\"/,"aB")
    gsub(/""/,"aC")

    # prepend previous incomplete record segment if any
    $0 = prev $0
    numq = gsub(/"/,"&")
    if ( numq % 2 ) {
        # this is inside double quotes so incomplete record
        prev = $0 OFS
        #prev = $0 RT   # uncomment to retain newlines in the record
        next
    }
    prev = ""

    for (i=1;i<=NF;i++) {
        # map the replacement strings back to their original values
        gsub(/aC/,"\"\"",$i)
        gsub(/aB/,"\\\"",$i)
        gsub(/aA/,"a",$i)
    }

    print

    #printf "Record %d:\n", ++recNr
    #for (i=0;i<=NF;i++) {
        #printf "\t$%d=<%s>\n", i, $i
    #}
    #print "#######"
}

.

$ awk -f decsv.awk file
137822118,user,User,192.168.100.20,2016-07-25 23:19:05 DST,iScript,iScript send MML command,B12345-BXL_ABCD_BD,Succeeded,"NE Name:B12345-BXL_ABCD_BD  ,MML Command:LST DEVIP:OPONEMS=""user"", IPOFEMSWS=""192.168.100.20"";  ,MML Result:Successful.  ,",2016-07-25 23:19:05 DST
137821234,user,User,192.168.100.21,2016-07-25 23:19:05 DST,iScript,iScript send MML command,B12345-BXL_ASDF_BD,Succeeded,"NE Name:B12345-BXL_ASDF_BD  ,MML Command:LST DEVIP:OPONEMS=""user"", IPOFEMSWS=""192.168.100.21"";  ,MML Result:Successful.  ,",2016-07-25 22:18:05 DST

См. Awk, чтобы получить столбец .csv, содержащий запятые и новые строки для получения дополнительной информации.

person Ed Morton    schedule 03.08.2016