Unix 用新值替换字符串
我试图处理一个大文件(+5.000.000条记录),因此我可以替换第8列的值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",
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
中设置替换映射。e、 g.r
是文字标记r[“1\”]=“成功”
(带qoutes!)到文字值“1”
(还包括引号!)的映射“success”
- 此外,
和FS
被设置为在OFS
部分中使用逗号作为输入和输出分隔符BEGIN
- 定义
后的部分包括一个测试,如果字段r
的值是映射中的一个键,如果是,则字段$8
将替换为映射$8
中为此键定义的值r
- 如果列
中存在未映射的值,则问题不是100%清楚,因此请将此作为您自己实验的起点$8
$ 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) }