我在Linux服务器上合并了许多文本文件,但有些文本文件略有不同,我需要统一它们。
例如,某些文件会有
这样的行id='1244' group='american' name='fred',american
其他文件就像
id='2345' name='frank', english
最后其他人会像
id='7897' group='' name='maria',scottish
我需要做的是,如果组=''或者字符串根本不在字符串中我需要在逗号之前将它添加到逗号之前的文本中,所以在上面的第二个例子中,该行将变为:
id='2345' name='frank' group='english',english
和最后一个将成为
的例子相同id='7897' name='maria' group='scottish',scottish
这是一个bash脚本。我无法删除该行并添加到文件的末尾,因为它与以下行相关。
我使用了以下内容:
sed -i.bak 's#group=""##' file
删除组=""字符串,这样行将包含group =' something'或根本不包含它,这是有效的
然后我尝试使用以下内容添加该组:
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
答案 0 :(得分:1)
类似
sed '
/^[^,]*group[^,]*,/ ! {
s/, *\(.*\)/ group='\''\1'\'', \1/
}
/^[^,]*group='\'\''/ {
s/group='\'\''\([^,]*\), *\(.*\)/group='\''\2'\''\1, \2/
}
'
答案 1 :(得分:1)
sed -r "
/group=''/ s/// # group is empty, remove it
/group=/! s/,[[:blank:]]*(.+)/ group='\\1',\\1/ # group is missing, add it
" file
id='1244' group='american' name='fred',american
foo
id='2345' name='frank' group='english',english
bar
id='7897' name='maria' group='scottish',scottish
foo和bar行未被触及,因为s ///命令与后跟字符的逗号不匹配。
答案 2 :(得分:0)
此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'
对。
如果找不到密钥group
或为空,则在到达只有一个字段的记录时会打印出来。
请注意,变量sq
包含单引号字符,用于检测空group
字段。
答案 3 :(得分:0)
Sed很难看。而且您的数据格式似乎有些不一致。这可能适合你:
$ sed -e "/group='[a-z]/b e" -e "s/group='' *//" -e "s/,\([a-z]*\)$/ group='\1', /" -e ':e' input.txt
为便于阅读而破碎,这是我们正在做的事情:
/group='[a-z]/b e
- 如果该行包含有效的group
,则分支到最后。s/group='' *//
- 删除所有空组,s/,\([a-z]*\)$/ group='\1', /
- 根据您的规范添加新组:e
- 第一个命令的分支标签。我真的不喜欢这样操纵数据。它容易出错,您将进一步将这些数据读入准确存储其数据结构的内容,然后根据新结构打印数据。一个更强大的解决方案可能直接与产生或消费这些数据的任何东西联系在一起,并且不会像这样处于中间位置。