2017-02-13 2 views
1

Я пытаюсь манипулировать огромным файлом (+5.000.000 записей), поэтому я могу заменить значение 8-го столбца, например.Замените строку новым значением

If $8 = 1 replace it with success 
if $8 = 2 replace it with check 
if $8 = null replace with undefined 

Вот часть данных, которая отделяется с помощью , характера:

"APPLICATION_ID","ORIGIN_ID","SERVICE_ID","PROVIDER_ID","RATING_ID","ATO","DATE","USER_TYPE","ESTATUS","OPERATION_ID" 

"3","2","424","5020","1058","3017292917","30/11/2016 01:14:25 a.m.","1","2004","14804862360104011458" 

поле Я хочу, чтобы заменить это USER_TYPE расположен на $8

Я попытался это, но это Безразлично» t заменить значения:

awk '{if($8 = 1) print $1, $2, $3, $4, $5, $6, $7, "success", $9, $10}' input_file 

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

+0

, как показано ниже, один '=' присваивает значение на РИТ к имени на LHS. Чтобы проверить равенство, используйте '==', поэтому 'if ($ 8 == 1) ...'. Вам также нужно указать 'awk' разделить поля на', 'char, либо с awk -F, '{...}' file' OR' awk 'BEGIN {FS = ","} {.... } 'файл'. Что происходит, когда '' '' внутри данных dbl-котировки? Kaboom! ... Намного лучше использовать char для разделения полей в вашем файле данных (или, может быть, '|' char). Удачи. – shellter

+0

Когда вам нужно иметь дело с csv, awk определенно не является хорошим способом, поскольку он не обрабатывает случаи, когда значение содержит разделитель. Вы должны использовать инструмент, предназначенный для работы с csv, например 'csvtool'. –

ответ

0

Вот короче один вкладыш:

$ awk 'BEGIN{FS=OFS=",";a[1]="success";a[2]="check"} {gsub(/"/,"",$8)} $8 in a{$8=a[$8]} 1' input.txt 

Разразившийся для комментирования:

BEGIN { 
    FS=OFS=","  # set our field separators 
    a[1]="success" # populate an array with replacement values 
    a[2]="check" 
} 

{ 
    gsub(/"/,"",$8) # remove quotes in field 8, for easier processing 
} 

$8 in a {   # check to see if field 8 is a member of our array 
    $8=a[$8]   # replace field 8 with the contents of the array at that index 
} 

1     # print the line 

Если это важно, чтобы держать кавычки вокруг каждого поля, вы можете сделать это, заменив присваивания с sprintf() в том числе:

$8=sprintf("\"%s\"",a[$8]) 

Помните, что awk знает только о вашем разделителе полей, а не о ваших кавычках. Если у вас есть поле, содержащее запятую внутри указанного поля, awk будет считать это разделителем полей. Вы можете добавить защиту для такого рода возникновения с чем-то вроде этого в верхней части сценария AWK:

NF != 10 { print "ERROR: wrong number of fields in line",NR > "/dev/stderr"; exit(1) } 
+0

прямо на деньги, он отлично работает, большое вам спасибо :) – sandatomo

+0

Yay, рад, что я мог бы помочь! :) (Я действительно удивляюсь, кто проиграл без комментария, хотя.) – ghoti

1

@sandatomo: Try (непроверенный):

awk -F, -vs1="\"" 'NR>1{gsub(/\"/,"",$8);if($8==1){sub(/.*/,s1 "success" s1,$8)};if($8==2){sub(/.*/,s1 "check" s1,$8)};if($8=="null"){sub(/.*/,s1 "undefined" s1,$8)};print}' OFS=, Input_file 

EDIT: Добавление неодномерной формы вкладыша из раствора тоже сейчас.

awk -F, -vs1="\"" 'NR>1{ 
           gsub(/\"/,"",$8); 
           if($8==1){ 
               sub(/.*/,s1 "success" s1,$8) 
             }; 
           if($8==2){ 
               sub(/.*/,s1 "check" s1,$8) 
             }; 
           if($8=="null"){ 
               sub(/.*/,s1 "undefined" s1,$8) 
               }; 
           print 
         } 
        ' OFS=, Input_file 

EDIT2: Я проверил мой код предыдущего кода, и он не имел разделитель поля, как «» так отредактирован сейчас.

EDIT3: Описание выше.

awk -F, -vs1="\"" 'NR>1{         ##### Setting Field separator as comma(,). Creating a variable named s1 whose value is a quote("). Then Checking here if current line number is greater than 1. 
                  ##### If above condition is TRUE then all following statements will be executing. 
       gsub(/\"/,"",$8);       ##### substituting all quotes(") in $8 now. 
     if($8==1){         ##### Check if 8th field value is 1, if yes then it will execute following statement. 
       sub(/.*/,s1 "success" s1,$8)  ##### substitute everything in $8 with s1 "success" s1 
       }; 
       if($8==2){         ##### Similarly like above checking if $8's value is 2 
       sub(/.*/,s1 "check" s1,$8)  ##### Then substitute the $8's value with s1 "check" s1 
       }; 
       if($8=="null"){       ##### checking if $8's value is "null" here 
       sub(/.*/,s1 "undefined" s1,$8) ##### substituting the complete value of $8 with s1 "undefined" s1. 
         }; 
     print          ##### printing the whole line now. 
     } 
    ' OFS=, Input_file         ##### Setting output field separator as a comma. Then mentioning the Input_file here. 
+0

Привет @ RavinderSingh13 Я дам ему попробовать, спасибо :) – sandatomo

+0

Привет всем (MOD), кто-то дал мне a -ve голосование за это решение. Я хотел бы попросить человека доброжелательно объяснить причину этого. Чтобы я мог улучшить свой ответ или отредактировать его в случае возникновения каких-либо ошибок/проблем. – RavinderSingh13

+0

@ RavinderSingh13 .. Мне также был предоставлен столь же полезный ниспровержение каким-то анонимным прохожим. Эти вещи случаются время от времени. Обвините троллей. – ghoti

0

Вы могли бы попробовать что-то вроде этого:

awk 'BEGIN {OFS=FS=",";r["\"\""] = "\"undefined\""; r["\"1\""]= "\"success\""; r["\"2\""]="\"check\""} {if($8 in r) $8 = r[$8]} 1' input_file 

Объяснение

  • в BEGIN части устанавливает заменяющий-отображение в r. например r["\"1\""]= "\"success\""; - это карта буквенного токена "1" (1 с qoutes!) До литерального значения "success" (также включая цитаты!)
  • дополнительно FS и OFS настроены на использование запятой в качестве входного и выходного сепаратора в BEGIN частях
  • части после определения r состоит из теста, если значение поля $8 является ключевым в карте, если да, то поле $8 заменяется значением, определенным на карте r по этому ключу
  • вопрос не на 100% неясен, если в столбце $8 задан вопрос, поэтому используйте это как отправную точку для своих собственных экспериментов
+0

, вероятно, лучше всего квалифицировать замену на '$ 8 in r', иначе удалят непревзойденные поля. – karakfa

+0

@LarsFischer спасибо за вашу помощь, я не знаю, почему, но с нулевыми полями это не сработало, может быть, это потому, что реализация awk, я использую Unix-машину HP-UX, приветствия – sandatomo

+0

Ларс, если вы 'set 'OFS', ваш вывод будет иметь поля, разделенные пробелом вместо запятых. Кроме того, было бы здорово, если бы вы могли объяснить, что ваше решение действительно * делает *, чтобы OP мог легче узнать из вашего ответа. – ghoti

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