【问题标题】:replace value if exist in a column of csv file [closed]如果存在于csv文件的列中,则替换值[关闭]
【发布时间】:2018-06-22 15:00:26
【问题描述】:

我需要找到 ip 前三个部分的所有值,如果重复,我将第四部分更改为 .255 。

例子:

216.239.35.207
216.239.35.209
216.239.35.209
209.85.255.97
209.85.255.97
216.239.35.207
216.239.35.207
216.239.35.209
216.239.35.207
216.239.35.207
216.239.35.207
216.239.35.207
216.239.35.209

变成

216.239.35.255
216.239.35.255
216.239.35.255
209.85.255.97
209.85.255.97
216.239.35.255
216.239.35.255
216.239.35.255
216.239.35.255
216.239.35.255
216.239.35.255
216.239.35.255
216.239.35.255

谢谢

【问题讨论】:

  • 为什么这个ip209.85.255.97没有被修改?
  • 因为这个ip和其他两个ip没有相同的三个前缀
  • 216.239.35.* 和另一个ip 209.85.255.*
  • 作为另外两个ip - 什么两个ip?前?下列的?你没有在你的问题中提到这一点。这并不明显。如果你暗示了什么——这并不意味着每个人都能认识到这一点
  • 请从awk 的初学者指南开始,并发布一些代码

标签: bash shell csv awk sed


【解决方案1】:

最后,这个shell脚本解决了这个问题:

#!/bin/bash

cat tt4 | sort -u | cut -d. -f1,2,3 > tmp1
awk 'BEGIN {while ((getline < "tmp1") > 0) { a[$0]++; if(a[$0] == 2) print; 
if (a[$0] >= 2) print }}' | sort -u > tmp2


while read line
 do 
 a=`echo $line |  cut -d. -f1,2,3`

   if [ `cat tmp2 | grep $a` ]; then

    fin=.255

    b=`echo $a$fin`
    echo $b

   else

   echo $line
   fi

 done < tt4

结果是

216.239.35.255
216.239.35.255
216.239.35.255
209.85.255.97
209.85.255.97
216.239.35.255
216.239.35.255
216.239.35.255
216.239.35.255
216.239.35.255
216.239.35.255
216.239.35.255
216.239.35.255
216.239.36.255
216.239.36.255

【讨论】:

  • 请澄清,如果 tt4 不包含以 209. 开头的行,(ie grep -v '^209.' tt4 的输出),第 4 个字段是否仍应更改?
  • 无论它必须以脚本开头的值是什么,都会检查前 3 个值是否存在并重复它会将第四个更改为 255 我测试了几个示例并且效果很好
  • 听起来好像您在说它正在寻找 三个 或更多的重复项——以 any 的顺序。请澄清,如果 tt4 包含 3 行以 grep -v '^209' tt4 的输出开头,那么以 209 开头的行是否应该更改其第 4 个字段?
  • 不,在这种情况下,它仅适用于链的前三个部分,即“209”。如果第四部分“.97”被改变,将被改变
  • 谢谢,现在假设以209. 开头的行是209.85.255.97209.85.255.98 -- those 的第四个字段是否应该更改为255
【解决方案2】:

根据OP's answer 修改了答案,他的代码似乎在寻找前三个字段重复的。如果只有一个块,不要管它,如果至少有两个块,(一个块的三个字段与另一个块),更改这些行的 4th 字段。

使用管道工具查找具有重复字段的块 1-3,然后使用 2nd uniq 仅查找重复块(要更改的块),然后使用这些生成一些sed 代码来完成这项工作:

cut -d. -f1,2,3 data | uniq -d | sort | uniq -d | 
sed 's#.*#/^&./s/.*/&.255/#' | sed -f - data

输出:

216.239.35.255
216.239.35.255
216.239.35.255
209.85.255.97
209.85.255.97
216.239.35.255
216.239.35.255
216.239.35.255
216.239.35.255
216.239.35.255
216.239.35.255
216.239.35.255
216.239.35.255

这个答案避免了:

  • 临时文件。
  • 幻数(ie 它不检查字段#3 或#4 是否等于97255,或类似的东西) .
  • shell 变量。

【讨论】:

  • 感谢您的回答,但目标是让 ip 保持 209 不变
【解决方案3】:

这可能对你有用(GNU sed):

sed -r 'N;s/(.*\.).*\n\1.*/\1255\n\1255/;P;D' file

将连续相似的 IP 地址更改为以255 结尾的一个

sed 's/216\.239\.35\..*/&255/' file

将特定类型的 IP 更改为以 255 结尾的 IP

【讨论】:

    【解决方案4】:

    正如您有根据的猜测所说,awk 是您的朋友。但老实说,你的问题非常简洁。你可以用类似下面的代码来做一些事情。请随意修改。

    # awk -v FS='.' -v OFS='.' 'BEGIN{i=1}NR==FNR{rec[i]=$0;$4="";pref[i++]=$0;next}
         END{
           pref[0]=pref[1];pref[i]=pref[i-1]
           for(i=1;i<=NR;i++){
             if(match(pref[i-1],pref[i+1]))
               sub(/.[0-9]+$/,".255",rec[i]);
             print rec[i];
    
           }
         }' case_file_48238278
    216.239.35.255
    216.239.35.255
    216.239.35.209
    209.85.255.97
    209.85.255.97
    216.239.35.207
    216.239.35.255
    216.239.35.255
    216.239.35.255
    216.239.35.255
    216.239.35.255
    216.239.35.255
    216.239.35.255
    

    【讨论】:

    • 使用此代码仅在最后一行进行更改
    • @MohamedRachedBenCheikh 我对此表示怀疑.. 您已经可以看到下面的输出
    • 我只是重新测试它,它不起作用
    猜你喜欢
    • 2013-12-23
    • 2021-01-14
    • 2014-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 2021-07-21
    相关资源
    最近更新 更多