2017-01-17 6 views
2

У меня есть файл CSV, который я прокладываю через набор команд awk/sed.Как заменить строку типа "[1.0 - 4.0]" на числовое значение с помощью awk или sed?

Некоторые строки в файле CSV выглядят как это:

10368,"Verizon DSL",DSL,NY,NORTHEAST,-5,-4,"[1.1 - 3.0]","[0.384 - 0.768]"  

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

Как использовать awk или sed, чтобы заменить эти поля на числовое значение? Либо начало диапазона, либо конец диапазона?

Так эта линия будет в конечном итоге, как

10368,"Verizon DSL",DSL,NY,NORTHEAST,-5,-4,1.1,0.384  

или

10368,"Verizon DSL",DSL,NY,NORTHEAST,-5,-4,3.0,0.768 

я добрался до removing the brackets, но прошлое, что я застрял. Я считал разделение на «-», но многие строки в моем файле имеют регулярное числовое значение, а не диапазон, в последних двух столбцах, и это делает вещи беспорядочными (я не хочу, чтобы в итоге были некоторые строки, имеющие разное количество столбцов).

ответ

2

Вот команда sed, которая будет принимать каждый диапазон и разбивать его на два поля. Он ищет строки, такие как "[A - B]" и преобразует их в A,B. Его можно легко изменить, чтобы просто использовать одно из значений, если это необходимо, изменив часть \1,\2. Регулярное выражение предполагает, что все числа имеют по крайней мере одну цифру по обе стороны от необходимого десятичного места. Таким образом, 1, .5 и 3. недействительны. Если вам это нужно, регулярное выражение может быть сделано более удобным.

$ cat file 
10368,"Verizon DSL",DSL,NY,NORTHEAST,-5,-4,"[1.1 - 3.0]","[0.384 - 0.768]" 
$ sed -Ee 's|"\[([0-9]+\.[0-9]+) - ([0-9]+\.[0-9]+)\]"|\1,\2|g' file 
10368,"Verizon DSL",DSL,NY,NORTHEAST,-5,-4,1.1,3.0,0.384,0.768 
+1

Для меня это «\ 1, \ 2», я не знал, что вы можете это сделать. Благодаря! – ff524

+1

вы можете прочитать о \ 1, \ 2 здесь http://www.grymoire.com/Unix/Sed.html – Vicky

1

Поскольку ваши данные поле основе, awk является логичным выбором.

Обратите внимание, что в то время как awk вообще не знает о двойных кавычках полей, что это не проблема здесь, потому что в двойных кавычках поля не имеют встроенных , экземпляров.

#!/usr/bin/env bash 

useStart1=1 # set to `0` to use the *end* of the *penultimate* fields' range instead. 
useStart2=1 # set to `0` to use the *end* of the *last* field's range instead. 
awk -v useStart1=$useStart1 -v useStart2=$useStart2 ' 
    BEGIN { FS=OFS="," } 
    { 
     split($(NF-1), tokens1, /[][" -]+/) 
     split($NF,  tokens2, /[][" -]+/) 
     $(NF-1) = useStart1 ? tokens1[2] : tokens1[3] 
     $NF =  useStart2 ? tokens2[2] : tokens2[3] 
     print 
    } 
' <<'EOF' 
10368,"Verizon DSL",DSL,NY,NORTHEAST,-5,-4,"[1.1 - 3.0]","[0.384 - 0.768]" 
EOF 

Код выше урожайности:

10368,"Verizon DSL",DSL,NY,NORTHEAST,-5,-4,1.1,0.384 

Изменение значения $useStart1 и $useStart2 дает соответствующие изменения.