我必须用其他数字替换列中数字的第一个实例。
这就是我要做的
输入:
54 679 75 98 21
24 543 86 98 43
42 543 54 98 55
93 255 25 98 25
43 523 43 98 31
98 775 24 76 78
77 564 65 76 45
输出:
54 679 75 98 21
24 543 86 98 43
42 543 54 98 55
93 255 25 98 25
43 523 43 98 31
98 775 24 91 78
77 564 65 76 45
因此,在第四列中首次出现的76
被91
取代。
这就是我尝试使用awk
进行的操作:
awk '{count=0;if ($4 == 76 && count < 1){ gsub("91","76")} count++; print}' input > output
但这没有帮助,有人可以提出建议吗?
答案 0 :(得分:4)
对stack0114106's answer进行一些调整,使其更加简洁:
awk '!t && $4==76 { $4=91; t=1;} 1 ' file
awk中未分配的变量将具有0
或空字符串值,将其取反将得到true
。
并且我将!t
放在另一个比较方程式之前是为了提高效率,因为&&
是一种快捷运算符,当第一部分的计算结果为false
时,它将阻止第二部分的执行。>
最后一个1
将在此处产生true
,一个无块的条件将隐含{print $0}
块。
答案 1 :(得分:3)
请您尝试以下操作(使用这种方法,我们提到的是变量中的所有值,没有任何硬编码,因为任何进一步的值更改只需更改变量值,程序就可以正常工作。)
awk -v column="4" -v count="1" -v value="76" -v new_value="91" '($column == value){if(++num==count){$column=new_value}} 1' Input_file
或添加非单一衬里形式的解决方案。
awk -v column="4" -v count="1" -v value="76" -v new_value="91" '
($column == value){
if(++num==count){
$column=new_value
}
}
1
' Input_file
输出如下。
54 679 75 98 21
24 543 86 98 43
42 543 54 98 55
93 255 25 98 25
43 523 43 98 31
98 775 24 91 78
77 564 65 76 45
编辑: :更正OP'尝试并添加更正详细信息。
代码应更改为:
awk '{if ($4 == 76){if(++count == 1){sub("^" 76 "$","91",$4)}};print}' Input_file
OP的代码上面的FIX解释:
count=0
在这里是一个错误,因为每次读取新行时,它将使变量count的值变为0,程序将永远不知道76
在第4个字段中出现了多少次,因此我删除了它。count<0
实际上应该是++count==1
并且应该位于条件$4==76
的块内,为什么因为前夕条件不是TRUE($4==76
)变量计数的值是继续增加,所以让我们增加,然后在条件$4==76
为TRUE时,它将正确保持其计数。gsub
,即使是固定的,仍然无法执行代码,原因是(g)sub
模式为sub(current_value,replaced_value)
,所以您用91
替换了76
与您的要求完全相反,在执行此FIX之后,您的代码应该可以正常工作:)答案 2 :(得分:2)
尝试这个简单的awk
awk -v t=1 ' $4==76 && t==1 { $4=91; t=0;} 1 ' file
要纠正您的尝试,只需将count的初始化包装在BEGIN块中并交换匹配项并替换gsub中的输入,即76和91
awk ' BEGIN {count=0; } { if ($4 == 76 && count < 1){ gsub("76","91"); count++; } print} ' input > output
使用您的输入
$ cat himanshu.txt
54 679 75 98 21
24 543 86 98 43
42 543 54 98 55
93 255 25 98 25
43 523 43 98 31
98 775 24 76 78
77 564 65 76 45
$ awk -v t=1 ' $4==76 && t==1 { $4=91; t=0;} 1 ' himanshu.txt
54 679 75 98 21
24 543 86 98 43
42 543 54 98 55
93 255 25 98 25
43 523 43 98 31
98 775 24 91 78
77 564 65 76 45
$
答案 3 :(得分:1)
如果您的awk
值可以位于任何列中,则可以使用以下76
命令:
awk '{for(i=1;i<=NF;i++){if($i == 76 && count < 1){count++; $i=91}}print}' input
54 679 75 98 21
24 543 86 98 43
42 543 54 98 55
93 255 25 98 25
43 523 43 98 31
98 775 24 91 78
77 564 65 76 45
答案 4 :(得分:1)
您的标题令人困惑:您想从gvim调用awk来编辑当前正在编辑的文件吗?在vim中做
^[^ ]\+ [^ ]\+ [^ ]\+ 76
输入 91
Esc 答案 5 :(得分:1)
这是我的解决方法
awk -v count=0 -v replace=76 -v replaceWith=91 'count==0&&$4==76{gsub("^" replace "$", replaceWith, $4); count++}1' sourceFile
使用了三个变量count
,replace
和replaceWith
count
用于计算搜索词的出现次数。在找到搜索词replace
之后,我增加了自己的代码,并确保没有借助表达式count == 0
replace
可以是列表中的任何值...不必进行硬编码。
与replaceWith
相同,您希望将值替换为
结果
awk -v count=0 -v replace=76 -v replaceWith=91 'count==0&&$4==76{sub("^" replace "$", replaceWith, $4); count++}1' sourceFile
54 679 75 98 21
24 543 86 98 43
42 543 54 98 55
93 255 25 98 25
43 523 43 98 31
98 775 24 91 78
77 564 65 76 45
在收到以下反馈后更改了脚本。将gsub
替换为$4 = replaceWith
awk -v count=0 -v replace=76 -v replaceWith=91 'count==0 && $4==replace{$4 = replaceWith; count++}1' sourceFile
54 679 75 98 21
24 543 86 98 43
42 543 54 98 55
93 255 25 98 25
43 523 43 98 31
98 775 24 91 78
77 564 65 76 45