BASH:拆分没有任何分隔符的字符串,只保留第一个子字符串

时间:2016-10-31 12:30:31

标签: regex bash csv split

我有一个包含7列的CSV文件,我只想修改第一列。实际上,在某些行中,行名称以连接方式出现 n 次,没有任何空格。我需要一个脚本,可以识别重复的开始位置并删除所有重复。

行名称的示例

行名= EXAMPLE1.ABC_DEF.panel4EXAMPLE1.ABC_DEF.panel4EXAMPLE1.ABC_DEF.panel4

替换为:EXAMPLE1.ABC_DEF.panel4

在不同的行中:

  • n 可能会有所不同

  • 行名称的长度可能会有所不同

  • 行名称的结构可能会有所不同(例如_.的数量),但总是整理而没有任何空格

我尝试了什么:

:%s/(.+)\1+/\1/

步骤一步:

  • %s:替换整个文件

  • (.+)\1+:第一个捕获组。 .+匹配任何字符(行终止符除外),+是量词 - 在一次和无限次之间匹配,尽可能多次,根据需要返回。

  • \1+:匹配第一个捕获组最近匹配的文本

  • 替换为\1

但是,我收到以下错误:

  • E65:非法反向引用

  • E476:无效命令

3 个答案:

答案 0 :(得分:0)

根据我的理解,您只需要一行包含EXAMPLE1.ABC_DEF.panel4。在这种情况下,您可以执行以下操作:

首先删除一行中的重复项:

sed -i "s/EXAMPLE1.ABC_DEF.panel4.*/EXAMPLE1.ABC_DEF.panel4/g"

然后删除重复的行:

awk '!a[$0]++'

答案 1 :(得分:0)

如果您的所有行都是您在问题中提供的格式(例如awk -F"EXAMPLE" '{print FS $2}' file ),那么这应该有用 -

awk

这需要"示例"作为字段分隔符并要求它仅打印第一列'。它预先设置"例子"到第一列(通过调用内置的FS变量getattr(self, method_name, self.generic_visit))。谢谢,@ andlrc。

不是一个理想的解决方案,但可能足以达到此目的。

答案 2 :(得分:0)

这个脚本,第一个arg是要测试的字符串,可以检索最大的重复子字符串(即“totototo”完成“toto”,而不是“to”)

#!/usr/bin/env bash
row_name="$1"
#test duplicate from the longest to the smallest, by how many we need to split the string ?
for (( i=2; i<${#row_name}; i++ ))
do
  match="True"
  #continue test only if it's mathematically possible
  if (( ${#row_name} % i )); then
    continue
  fi
  #length of the potential duplicate substring
  len_sub=$(( ${#row_name} / i ))
  #test if the first substring is equal to each others
  for (( s=1; s<i; s++ ))
  do
    if ! [ "${row_name:0:${len_sub}}" = "${row_name:$((len_sub * s)):${len_sub}}" ]; then
      match="False"
      break
   fi
  done
  #each substring are equal, so return string without duplicate
  if [ $match = "True" ]; then
    row_name="${row_name:0:${len_sub}}"
    break
  fi
done
echo "$row_name"