Можно использовать много различных инструментов для этого. 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
.
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
Здесь я предположил, что разделение всегда выполняется непосредственно перед запятой ,
.
Давайте возьмем это как тестовый файл:
$ 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 ""}
Когда мы дойдем до конца файла, выведите еще одну новую строку, чтобы завершить последнюю строку.