我有一个数据,如下所示在文件test.cs中
using System;
using System.Data;
using Sample.test.value;
namespace Sample.test {
class testclass{
public testclass(){
}
}
}
我希望输出为
namespace Sample.test {
using System;
using System.Data;
using value;
class testclass{
public testclass(){
}
}
}
我只想通过使用sed来实现
我尝试使用以下sed脚本,并且能够复制并粘贴using内部名称空间
/^using/{
H
d
}
/^namespace/{
G
}
但是无法在using语句中替换名称空间。在此示例中,我以“ Sample.test”命名空间为例。但实际上,它可以是任何东西。
答案 0 :(得分:1)
可以使用awk
。但不确定是什么触发了该动作以及它如何作用于您的真实数据。
awk '/^using/ {s=s"\n"$0;next} /^namespace/ {print $0 s;next} 1' file
namespace Sample.test {
using System;
using System.Data;
using Sample.test.value;
class testclass{
public testclass(){
}
}
}
答案 1 :(得分:1)
这可能对您有用(GNU sed):
sed '/using/{s/^/ /;s/Sample\.test\.//;H;d};/namespace/{p;g;s/.//;n;/^$/d}' file
在保留空间中收集包含using
的行,但首先添加一个前导空格并删除所有Sample.test.
字符串。遇到namespace
时,打印该行,附加保留空间,删除前导换行符,打印这些行,然后获取下一行,如果为空则将其删除。
答案 2 :(得分:1)
此sed脚本可转换您的测试数据,但是如果您的文件包含多个using / namespace块,或者空白不相同,则将需要更改。
# match using lines
/^using/{
s/^/ / # prepend whitespace
H # append to hold
d # don't print (yet)
}
# match namespace lines
/^namespace/{
G # append the using block after namespace line
# loop while we can strip a namespace name from a using line
:a
s/\(\([^ ]*\) {.*using \)\2\./\1/
ta
# read in next line and delete it if empty
N
s/\n\n/\n/g
}
# implicit print
第二个s///
命令查找{
之前的名称(即\([^ ]*\)
),然后是带有相同名称的using
行和句点(即\2\.
)。由于结尾\2\.
... \1
的初始集合,因此末尾\(
之外的整个匹配项都可以作为\)
使用,并替换了原始文本。
基于@Jotne的答案,等效的awk版本是:
/^using/ {
# store using lines, along with a prepended space
a[++i] = " " $0
next
}
/^namespace/ {
print
# strip namespace name from using lines, then print
r = " " $2 "[.]"
for(i in a) {
sub(r, " ", a[i])
print a[i]
}
# delete subsequent line if it is blank
getline
if ($0) print
next
}
# print every other line
1
此处的正则表达式(r
)后面是空格,然后是名称空间名称(在名称空间行上应为$2
)和句点。 sub()
仅用一个空格替换保存的使用行的此正则表达式。