Hi,
I have a following file and it has only one occurrence of line that says "Output view:". It could be in middle somewhere ( i don't know the exact location ). I want to move it as the first line of the file.
Input
AAA
BBBB
CCCC
Output view:
XXXX
YYYY
ZZZZ
Output should be:
Output view:
AAA
BBBB
CCCC
XXXX
YYYY
ZZZZ
sed '/Output view:/d;1i\Output view:' file
Emanuele
ctsgnb
October 16, 2013, 9:28am
3
Lazy (but easy to read) solution...
grep "Output view:" input >output
grep -v "Output view:" input >>output
But no doubt it must be some more elegant solution ...
@Alister :
Any "ed" suggestion ?
Hi,
Another sed solution (also work with regular expression):
sed -n '1,/Output view:/{/Output view:/{G;s/\n//p;b;};H;b};p' file
Regards.
Yet another way with the trusty ole ex...
ex -s +'/^Output view:/m0 | x' file
1 Like
Two more:
awk '/Output view:/{f=1; $0=$0 p; p=x} !f{p=p RS $0} f' file
or perhaps simply
awk 'NR==1{print s} $0!~s' s="Output view:" file
1 Like
ctsgnb:
Lazy (but easy to read) solution...
grep "Output view:" input >output
grep -v "Output view:" input >>output
But no doubt it must be some more elegant solution ...
@Alister :
Any "ed" suggestion ?
#!/bin/ksh
infile="Input"
outfile="Output"
ed -s "$infile" <<-EOF
/Output view:/m0
w $outfile
q
EOF
This was tested using the Korn shell, but will work with any shell that accepts basic Bourne shell syntax.
1 Like
Hi,
May be this code can help too.
$ awk '
BEGIN{
print "Output view:"
} NR==4 || /Output/ {next} {print $1}' file_name
Output will be as follows.
Output view:
AAA
BBBB
CCCC
XXXX
YYYY
ZZZZ
Thanks,
R. Singh
Nice.
I found this about the use of + :
The -c replacement for + command was inspired by the -e option of sed. Historically, all such commands (see edit and next as well) were executed from the last line of the edit buffer. This meant, for example, that "+/pattern" would fail unless the wrapscan option was set. POSIX.1-2008 requires conformance to historical practice. The + command option is no longer specified by POSIX.1-2008 but may be present in some implementations. Historically, some implementations restricted the ex commands that could be listed as part of the command line arguments. For consistency, POSIX.1-2008 does not permit these restrictions.
ex: Rationale - options
This seems to work too:
ex -sc '/^Output view:/m0 | x' file
1 Like
One more lengthy way
may try
$ awk 'BEGIN{while(1){getline;if(/Output/){printf $0;break}x=x RS $0}print x}1' file
OR
$ awk '{if(/Output/)printf $0;else x=x RS $0}END{print x}' file
Resulting
Output view:
AAA
BBBB
CCCC
XXXX
YYYY
ZZZZ
2 Likes
sed -e '/^Output view:/{G;p;}' -e '1{h;d;}' -e '2,/^Output view:/{H;d;}' file
maybe better readable as
sed '
/^Output view:/{G;p;}
1{h;d;}
2,/^Output view:/{H;d;}
' file
But sed is hacking; the string must be mentioned twice. awk is better:
awk 'p; /^Output view:/ {print; print s; p=1} !p {s=s sep $0; sep=RS}' file
sir,
code
awk '/Output view:/{f=1; $0=$0 p; p=x} !f{p=p RS $0} f' file
works fine. But can you explain me step by step by step how it works.
Reformatting Scrutinizer's code and adding comments:
awk ' # invoke awk program and start script to be run by awk
/Output view:/ {# When an input line contains the string "Output view:"...
f=1 # set f (found) to 1,
$0=$0 p # append the contents of p to the end of the
# current input line, and
p=x # set p to the contents of x (an empty string)
}
!f { # If f is 0...
p=p RS $0 # append the record separator (default value is
# the newline character) and the current input
# line to p
}
f $ If f is not 0, print the current input line.
' file # End awk script and specify the name of the input file.
4 Likes