我有一个包含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:无效命令
答案 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"