【问题标题】:Replace repeated elements in a list with unique identifiers用唯一标识符替换列表中的重复元素
【发布时间】:2014-02-15 18:53:46
【问题描述】:

我有一个如下列表:

1 . Fred 1 6 78 8 09
1 1 Geni 1 4 68 9 34
2 . Sam 3 4 56 6 89
3 . Flit 2 4 56 8 34
3 4 Dog 2 5 67 8 78
3 . Pig 2 5 67 2 21

(除了实际的列表是 4000 万行)。

第二列有重复的元素(即“.”)

我想将这些替换为唯一标识符(例如“.1”、“.2”、“.3”...“。n”)

我尝试使用 bash 循环/sed 组合来执行此操作,但没有成功...

尝试失败:

for i in 1..4
  do
    sed -i "s_//._//."$i"_"$i""
  done 

(基本上,我试图让 sed 用“.n”替换每个第 n 个“.”,但这不起作用)。

【问题讨论】:

    标签: bash replace sed rename


    【解决方案1】:

    这是使用awk 的一种方法(假设您的文件名为input

    $ awk '$2=="."{$2="."++counter}{print}' input 
    1 .1 Fred 1 6 78 8 09
    1 1 Geni 1 4 68 9 34
    2 .2 Sam 3 4 56 6 89
    3 .3 Flit 2 4 56 8 34
    3 4 Dog 2 5 67 8 78
    3 .4 Pig 2 5 67 2 21
    

    awk 程序将第二列 ($2) 替换为由 . 和预递增计数器 (++counter) 连接形成的字符串,如果第二列正好是 .。然后它打印出它得到的所有列($2 修改与否)({print})。

    简单的 bash 替代方案:

    c=1
    while read -r a b line ; do
      if [ "$b" == "." ] ; then
        echo "$a ."$((c++))" $line"
      else
        echo "$a $b $line"
      fi
    done < input
    

    【讨论】:

    • 我不知道如何使用 sed 来做到这一点。不过,here 的一些答案可能会有所帮助。
    【解决方案2】:

    你可以使用这个命令:

    awk '{gsub(/\./,c++);print}' filename
    

    输出:

    1 0 Fred 1 6 78 8 09
    1 1 Geni 1 4 68 9 34
    2 2 Sam 3 4 56 6 89
    3 3 Flit 2 4 56 8 34
    3 4 Dog 2 5 67 8 78
    3 5 Pig 2 5 67 2 21
    

    【讨论】:

      【解决方案3】:

      由于您的问题被标记为 sedbash,因此这里有几个示例以确保完整性。

      仅限 Bash

      使用parameter expansion。第二列将是唯一的,但不是连续的:

      i=1; while read line; do echo ${line/\./.$((i++))}; done < input
      
      1 .1 Fred 1 6 78 8 09
      1 1 Geni 1 4 68 9 34
      2 .3 Sam 3 4 56 6 89
      3 .4 Flit 2 4 56 8 34
      3 4 Dog 2 5 67 8 78
      3 .6 Pig 2 5 67 2 21
      

      Bash + sed

      sed 不能增加变量,它必须在外部完成。

      对于每一行,如果行包含.,则递增$i,然后让sed. 之后附加$i

      i=0                                    
      while read line; do                 
          [[ $line == *.* ]] && i=$((i+1))   
          sed "s#\.#.$i#" <<<"$line" 
      done < input                           
      

      输出:

      1 .1 Fred 1 6 78 8 09
      1 1 Geni 1 4 68 9 34
      2 .2 Sam 3 4 56 6 89
      3 .3 Flit 2 4 56 8 34
      3 4 Dog 2 5 67 8 78
      3 .4 Pig 2 5 67 2 21
      

      【讨论】:

        猜你喜欢
        • 2020-03-25
        • 2021-05-19
        • 2011-03-18
        • 2013-11-19
        • 2019-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多