Unix 用新值替换字符串

Unix 用新值替换字符串,unix,awk,Unix,Awk,我试图处理一个大文件(+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",

我试图处理一个大文件(+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\u TYPE
,位于
$8

我尝试了这个方法,但它不能替换以下值:

awk '{if($8 = 1) print $1, $2, $3, $4, $5, $6, $7, "success", $9, $10}' input_file
我如何才能做到这一点?

@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
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.

您可以尝试以下方法:

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

  • BEGIN
    零件在
    r
    中设置替换映射。e、 g.
    r[“1\”]=“成功”
    是文字标记
    “1”
    (带qoutes!)到文字值
    “success”
    (还包括引号!)的映射
  • 此外,
    FS
    OFS
    被设置为在
    BEGIN
    部分中使用逗号作为输入和输出分隔符
  • 定义
    r
    后的部分包括一个测试,如果字段
    $8
    的值是映射中的一个键,如果是,则字段
    $8
    将替换为映射
    r
    中为此键定义的值
  • 如果列
    $8
    中存在未映射的值,则问题不是100%清楚,因此请将此作为您自己实验的起点

这里有一条较短的单线:

$ 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) }

如下所示,单个
=
将RHS上的值分配给LHS上的名称。要测试是否相等,请使用
=
,因此
如果($8==1)…
。您还需要告诉
awk
拆分
字符上的字段,使用awk-F,{…}文件`或
awk'BEGIN{FS=“,”}{…}文件
。当dbl引用的数据中有
s时会发生什么?卡布姆。。。所以最好使用字符来分隔数据文件中的字段(或者可能是
|
char)。祝你好运。当你需要处理csv时,awk肯定不是一个好方法,因为它不处理值包含分隔符的情况。您应该使用专门用于处理csv的工具,例如
csvtool
。最好在r中使用
$8进行替换,否则将删除不匹配的字段。@Larsfisher感谢您的帮助,我不知道为什么,但对于空字段,它不起作用,可能是因为awk实现,我使用的是HP-UX unix机器,问候语,如果您不设置OFS
,您的输出将包含由空格而不是逗号分隔的字段。此外,如果您能解释您的解决方案的实际作用,以便OP能更容易地从您的答案中学习,那将是非常好的。@sandatomo请在问题中指定您所说的
空字段
是什么意思。最好给出一个输入和输出行的示例
null字段
可以是
”、
null
“null”
,也可以是两个逗号之间的空字符串。@Larsfisher,您好,很抱歉,我花了这么长时间才做出响应。在这种情况下,null字符串是这样的“只是双引号,中间没有任何内容。对钱来说,它工作得很好,非常感谢:)耶,很高兴我能帮忙!:)(我真想知道是谁在没有任何评论的情况下否决了投票。)嗨@RavinderSingh13我会尝试一下,谢谢:)大家好(MODs),有人给了我关于这个解决方案的-ve票。我想请您提供同样的原因。这样我就可以改进我的答案或编辑它,以防其中出现任何错误/问题。@RavinderSingh13。。我也被一些匿名的路人投了同样有益的反对票。这些事情时有发生。怪罪那些巨魔。@ghoti:谢谢你让我知道(因为我也是一个新手,只在堆栈溢出方面),我坚信我们应该有一个授权部分,如果有人投了反对票,那么其他人完全有权知道他/她在解决方案中做错了什么,这样我们也可以改进自己和发布/线程。作为惯例,这已经存在。但作为一项策略,它需要某种强制执行,因此需要对运行该策略的底层代码进行更改。我确信这已经在Meta中讨论过了,但是再次提到它并没有什么坏处,因为这是一个不会自行消失的问题。
NF != 10 { print "ERROR: wrong number of fields in line",NR > "/dev/stderr"; exit(1) }