Regex 如果该行没有';不能使用sed包含另一个字符串
我在linux服务器上合并了许多文本文件,但其中一些行略有不同,我需要统一它们 例如,某些文件将具有类似于Regex 如果该行没有';不能使用sed包含另一个字符串,regex,bash,sed,Regex,Bash,Sed,我在linux服务器上合并了许多文本文件,但其中一些行略有不同,我需要统一它们 例如,某些文件将具有类似于 id='1244' group='american' name='fred',american 其他文件将类似于 id='2345' name='frank', english id='7897' group='' name='maria',scottish 最后其他人也会这样 id='2345' name='frank', english id='7897' group='' n
id='1244' group='american' name='fred',american
其他文件将类似于
id='2345' name='frank', english
id='7897' group='' name='maria',scottish
最后其他人也会这样
id='2345' name='frank', english
id='7897' group='' name='maria',scottish
我需要做的是,如果group=''或group根本不在字符串中,我需要将其添加到逗号之前的某个位置,将其设置为逗号之后的文本,因此在第二个示例中,该行上方将变为:
id='2345' name='frank' group='english',english
在最后一个例子中也是一样的
id='7897' name='maria' group='scottish',scottish
这将进入bash脚本。实际上,我不能删除该行并将其添加到文件末尾,因为它与下一行相关
我使用了以下方法:
sed -i.bak 's#group=""##' file
sed -i.bak '/group/! s#,(.*$)#group="\1",\1#' file
这将删除group=”“字符串,因此行将包含group='something'或根本不包含它,这样就可以了
然后,我尝试使用以下方法添加不存在的组:
sed -i.bak 's#group=""##' file
sed -i.bak '/group/! s#,(.*$)#group="\1",\1#' file
但这就产生了错误
sed: -e expression #1, char 38: invalid reference \1 on `s' command's RHS
编辑Ed Morton编写的以创建单个示例输入文件和预期输出:
样本输入:
id='1244' group='american' name='fred',american
foo
id='2345' name='frank', english
bar
id='7897' group='' name='maria',scottish
预期产出:
id='1244' group='american' name='fred',american
foo
id='2345' name='frank' group='english',english
bar
id='7897' name='maria' group='scottish',scottish
差不多
sed '
/^[^,]*group[^,]*,/ ! {
s/, *\(.*\)/ group='\''\1'\'', \1/
}
/^[^,]*group='\'\''/ {
s/group='\'\''\([^,]*\), *\(.*\)/group='\''\2'\''\1, \2/
}
'
此GNU
awk
可能有助于:
awk -v sq="'" '
BEGIN{RS="[ ,\n]+"; FS="="; found=0}
$1=="group"{
if($2==sq sq)
{next}
else
{found=1}
}
NF>1{
printf "%s=%s ",$1,$2
}
NF==1{
if(!found)
{printf "group=%s",$1}
print ","$1
found=0
}
' file
脚本依赖于记录分隔符RS
,该分隔符设置为获取所有key='value'
对
如果未找到键组
或键为空,则在到达只有一个字段的记录时将打印该键
请注意,变量
sq
包含单引号字符,用于检测空的组
字段。Sed可能非常难看。而且您的数据格式似乎有些不一致。这可能适合您:
$ sed -e "/group='[a-z]/b e" -e "s/group='' *//" -e "s/,\([a-z]*\)$/ group='\1', /" -e ':e' input.txt
为了便于阅读,我们正在做以下工作:
-如果行包含有效的/group='[a-z]/be
,则分支到末尾组
-删除任何空组s/group=''*/
-根据您的规格添加一个新组s/,\([a-z]*\)$/group='\1',/
-第一个命令的分支标签:e
- 然后默认操作是打印行
sed -r "
/group=''/ s/// # group is empty, remove it
/group=/! s/,[[:blank:]]*(.+)/ group='\\1',\\1/ # group is missing, add it
" file
foo和bar行未被触及,因为s///命令与后跟字符的逗号不匹配。到目前为止您尝试了什么?让我们看一些代码:-)抱歉,我编辑了我的问题以显示我的尝试。在BRE(基本正则表达式)语法中,sed的默认模式语法,捕获组的括号必须转义:
\(.*$\)
,否则,它们被视为文字字符。我编辑了您的问题,试图提供一个示例输入文件和给定该输入的预期输出。如果它是错误的,那么请修复它。一堆单独的输入行,一些有预期的输出,一些没有,并且没有一行有周围行的上下文,几乎没有上下文的一个具体示例有用。这为我指明了正确的方向,它似乎完全按照所描述的那样做,但EOL似乎把它搞砸了。我得到的输出像id='7897'name='maria'group='scottish,所以错过了小组的最后一个'和逗号之后的文本。我的最新版本可能是因为我已经在文件上使用了sed-I-e“s/^m//g”?#听起来像是停留回车s/\r$/
使用回车符,我希望您会看到行尾覆盖行首:,苏格兰名称='maria'group='scottish