Issue
I have a data which is shown like below in a file test.cs
using System;
using System.Data;
using Sample.test.value;
namespace Sample.test {
class testclass{
public testclass(){
}
}
}
I want the output to be
namespace Sample.test {
using System;
using System.Data;
using value;
class testclass{
public testclass(){
}
}
}
This i want to achieve only by using sed
I tried below sed script and able to copy and paste the using inside namespace
/^using/{
H
d
}
/^namespace/{
G
}
But unable to replace the namespace in using statement. Here in this example I took an example as "Sample.test" namespace. But it real case it can be anything.
Solution
This sed script transforms your test data but will need alteration if your files contain more than one using/namespace block, or if the whitespace is not identical.
# 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
The second s///
command looks for the name that precedes a {
(ie. \([^ ]*\)
) followed by a using
line with that same name followed by a period (ie. \2\.
). The entirety of the match aside from the trailing \2\.
is available as \1
because of the initial set of \(
...\)
and replaces the original text.
Note: Using \n
in the replacement is not portable. If using a version of sed that does not understand it, use an escaped literal newline:
# ...
N
s/\n\n/\
/g
}
Building on @Jotne's answer, an equivalent awk version is:
/^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
The regex here (r
) looks for a space followed by the namespace name (it should be $2
on the namespace line) followed by a period. The sub()
replaces any occurrences of this regex in the saved using lines with just a single space.
Answered By - jhnc Answer Checked By - Cary Denson (WPSolving Admin)