Как обнаружить и удалить символ новой строки в столбце файла CSV?

Можно использовать много различных инструментов для этого. Rahul Patil уже дал Вам a gawk один, таким образом, вот немногие другие:

  • жемчуг

    perl -lane  '$F[0]=~s/\./-/g; print "@F"' file
    

    -a переключите жемчуг причин, чтобы автоматически разделить входные строки на пробеле и сохранить получающиеся поля в массив @F. Первое поле, поэтому, будет $F[0] таким образом, мы заменяем (s///) все случаи . с - в первом поле и затем печатают целый массив.

  • оболочка

     while read -r a b; do printf "%s %s\n" "${a//./-}" "$b"; done < file 
    

    Здесь, цикл с условием продолжения читает файл и автоматически разделяет на пробеле. Это создает два поля, $first и $rest. Конструкция ${first//pattern/replacement} замены все случаи pattern с replacement.

2
23.05.2017, 14:33
2 ответа

perl приходит на помощь:

$ perl -p00e 's/\n,/,/g' file
playerID,yearID,gameNum,gameID,teamID,lgID,GP,startingPos
gomezle01,1933,0,ALS193307060,NYA,AL,1,1
ferreri01,1933,0,ALS193307060,BOS,AL,1,2
gehrilo01,1933,0,ALS193307060,NYA,AL,1,3
gehrich01,1933,0,ALS193307060,DET,AL,1,4
dykesji01,1933,0,ALS193307060,CHA,AL,1,5
cronijo01,1933,0,ALS193307060,WS1,AL,1,6
chapmbe01,1933,0,ALS193307060,NYA,AL,1,7
simmoal01,1933,0,ALS193307060,CHA,AL,1,8
ruthba01,1933,0,ALS193307060,NYA,AL,1,9

Здесь я предположил, что разделение всегда выполняется непосредственно перед запятой , .

1
27.01.2020, 21:59

Давайте возьмем это как тестовый файл:

$ cat file
playerID,yearID,gameNum,gameID,teamID,lgID,GP,startingPos
gomezle01,1933,0,ALS193307060,NYA,AL,1,1
ferreri01,1933,0,ALS193307060,BOS,AL,1,2
gehrilo01,1933,0
,ALS193307060,NYA,AL,1,3
gehrich01,1933,0,ALS193307060,DET,AL,1,4
dykesji01,1933,0,ALS193307060,CHA,AL,1,5
cronijo01,1933,0,ALS193307060
,WS1,AL,1,6
chapmbe01,1933,0,ALS193307060,NYA,AL,1,7
simmoal01,1933,0,ALS193307060,CHA,AL,1,8
ruthba01,1933,0,ALS193307060,NYA,AL,1,9
Bill
Gates,1933,0,ALS193307060,NYA,AL,1,9

Это снова объединяет строки:

$ awk 'NR==1{printf "%s",$0; gsub(/[^,]/,""); nlast=n=length($0); next;} nlast==n{printf "\n";nlast=0} {printf "%s",$0; gsub(/[^,]/,""); nlast+=length($0)} END{print ""}' file
playerID,yearID,gameNum,gameID,teamID,lgID,GP,startingPos
gomezle01,1933,0,ALS193307060,NYA,AL,1,1
ferreri01,1933,0,ALS193307060,BOS,AL,1,2
gehrilo01,1933,0,ALS193307060,NYA,AL,1,3
gehrich01,1933,0,ALS193307060,DET,AL,1,4
dykesji01,1933,0,ALS193307060,CHA,AL,1,5
cronijo01,1933,0,ALS193307060,WS1,AL,1,6
chapmbe01,1933,0,ALS193307060,NYA,AL,1,7
simmoal01,1933,0,ALS193307060,CHA,AL,1,8
ruthba01,1933,0,ALS193307060,NYA,AL,1,9
BillGates,1933,0,ALS193307060,NYA,AL,1,9

Требования к завершению строки мне не ясны. Мы могли бы добавить сюда код для его обработки. Или, для большей гибкости, вы можете запустить файл через dos2unix или unix2dos по мере необходимости.

Ответ на первую версию вопроса

У меня большой (2 миллиона строк) CSV-файл

Это строчно-ориентированное решение, которое не требует одновременного чтения всего файла в память:

$ awk 'NR>1 && !/^,/{printf "\n";} {printf "%s",$0} END{print ""}' file
playerID,yearID,gameNum,gameID,teamID,lgID,GP,startingPos
gomezle01,1933,0,ALS193307060,NYA,AL,1,1
ferreri01,1933,0,ALS193307060,BOS,AL,1,2
gehrilo01,1933,0,ALS193307060,NYA,AL,1,3
gehrich01,1933,0,ALS193307060,DET,AL,1,4
dykesji01,1933,0,ALS193307060,CHA,AL,1,5
cronijo01,1933,0,ALS193307060,WS1,AL,1,6
chapmbe01,1933,0,ALS193307060,NYA,AL,1,7
simmoal01,1933,0,ALS193307060,CHA,AL,1,8
ruthba01,1933,0,ALS193307060,NYA,AL,1,9

Как он работает

  • NR> 1 &&! / ^, / {printf "\ n";}

    Если мы не на первой строке, NR> 1 , и текущая строка не начинаются с запятой, ! / ^, / , выводится новая строка.

  • {printf "% s", $ 0}

    Печатать текущую строку без новой строки.

  • END {print ""}

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

3
27.01.2020, 21:59

Теги

Похожие вопросы