我有一个具有这种结构的数据库:
word1#element1.1#element1.2#element1.3#...
word2#element2.1#element2.2#element2.3#...
...
...
每当开头的单词相同时,我想统一2行或更多行的元素 例如:
...
word8#element8.1#element8.2#element8.3#...
word9#element9.1#element9.2#element9.3#...
...
现在,让我们假设word8 = word9,这就是结果:
...
word8#element8.1#element8.2#element8.3#...#element9.1#element9.2#element9.3#...
...
我尝试使用sed
命令:
N
^\([^#]*\)
(所有元素都用'#'表示)\([^\n]*\)
\n
之后)是否出现相同的字词:\1
\1#\2
这是完整的代码:
sed 'N;s/^\([^#]*\)#\([^\n]*\)\n\1/\1#\2/' database
我想了解为什么它不起作用以及如何解决这个问题。
非常感谢你。
答案 0 :(得分:3)
这可能适合你(GNU sed):
sed 'N;s/^\(\([^#]*#\).*\)\n\2/\1#/;P;D' file
始终读取2行,如果这两行开头的单词匹配,则删除换行符和第二行的匹配部分(恢复#
)。
答案 1 :(得分:1)
sed '#n
H
$ { x
:cycle
s/\(\n\)\([^#]*#\)\([^[:cntrl:]]*\)\1\2/\1\2\3#/g
t cycle
s/.//
p
}' YourFile
假设单词已排序
#
作为seprator)答案 2 :(得分:1)
您可以尝试使用perl。它逐行读取输入文件,分成第一个#
字符,并使用hash
arrays
将第一个单词保存为键,并将该行的其余部分附加为值。在END
块,它按第一个单词排序并加入行:
perl -lne '
($key, $line) = split /#/, $_, 2;
push @{$hash{$key}}, $line;
END {
for $k ( sort keys %hash ) {
printf qq|%s#%s\n|, $k, join q|#|, @{$hash{$k}};
}
}
' infile
答案 3 :(得分:1)
使用文字替换:
perl -p0E 'while( s/(^|\n)(.+?#)(.*)\n\2(.*)/$1$2$3 $4/ ){}' yourfile
或缩进:
perl -p0E 'while( # while we can
s/(^|\n) # substitute \n
(.+?\#) (.*) \n # id elems1
\2 (.*) # id elems2
/$1$2$3 $4/x # \n id elems1 elems2
){}'
谢谢:@birei
答案 4 :(得分:1)
$ cat file
word1#element1.1#element1.2#element1.3
word2#element2.1#element2.2#element2.3
word8#element8.1#element8.2#element8.3
word8#element9.1#element9.2#element9.3
word9#element9.1#element9.2#element9.3
$ awk 'BEGIN{FS=OFS="#"}
NR>1 && $1!=prev { print "" }
$1==prev { sub(/^[^#]+/,"") }
{ printf "%s",$0; prev=$1 }
END { print "" }
' file
word1#element1.1#element1.2#element1.3
word2#element2.1#element2.2#element2.3
word8#element8.1#element8.2#element8.3#element9.1#element9.2#element9.3
word9#element9.1#element9.2#element9.3