From: Hongyi Zhao on
Hi all,

I want to swap the appearance order of two lines in a file if needed.
For detail, please see the following minimal example:

....
here_comes_line_b
....
here_comes_line_a
....


Suppose the following should be the final result I want:

....
here_comes_line_a
....
here_comes_line_b
....

Furthermore, in my file, line_a and line_b only occur once.

What code should I use?
--
..: Hongyi Zhao [ hongyi.zhao AT gmail.com ] Free as in Freedom :.
From: WANG Cong on
On Tue, 24 Nov 2009 17:34:47 +0800, Hongyi Zhao wrote:

> Hi all,
>
> I want to swap the appearance order of two lines in a file if needed.
> For detail, please see the following minimal example:
>
> ...
> here_comes_line_b
> ...
> here_comes_line_a
> ...
>
>
> Suppose the following should be the final result I want:
>
> ...
> here_comes_line_a
> ...
> here_comes_line_b
> ...
>
> Furthermore, in my file, line_a and line_b only occur once.
>
> What code should I use?

perl -e '@_ = <STDIN>; ($_[$ARGV[0]-1], $_[$ARGV[1]-1])=($_[$ARGV[1]-1],
$_[$ARGV[0]-1]); print @_;' `grep -n here_comes_line_b your_file | cut -
d: -f1` `grep -n here_comes_line_a your_file | cut -d: -f1` < your_file


From: Ed Morton on
Hongyi Zhao wrote:
> Hi all,
>
> I want to swap the appearance order of two lines in a file if needed.
> For detail, please see the following minimal example:
>
> ...
> here_comes_line_b
> ...
> here_comes_line_a
> ...
>
>
> Suppose the following should be the final result I want:
>
> ...
> here_comes_line_a
> ...
> here_comes_line_b
> ...
>
> Furthermore, in my file, line_a and line_b only occur once.
>
> What code should I use?

Either use an array to hold the whole file:

awk '{file[NR]=$0} /here_comes_line_a|here_comes_line_b/{swap[++cnt]=NR}
END{ tmp=file[swap[1]]; file[swap[1]]=file[swap[2]]; file[swap[2]]=tmp
for (i=1;i<=NR;i++) print file[i] }' file

or do two passes of the file:

awk 'NR==FNR{ if (/here_comes_line_a/) a[NR]=$0
else if (/here_comes_line_b/) b[NR]=$0
next
}
NR in a { $0 = b[NR] }
NR in b { $0 = a[NR] }
1' file file

Both untested.

Regards,

Ed.
From: Glenn Jackman on
At 2009-11-24 08:12AM, "Ed Morton" wrote:
> Hongyi Zhao wrote:
> > Hi all,
> >
> > I want to swap the appearance order of two lines in a file if needed.
> > For detail, please see the following minimal example:
> >
> > ...
> > here_comes_line_b
> > ...
> > here_comes_line_a
> > ...
> >
> >
> > Suppose the following should be the final result I want:
> >
> > ...
> > here_comes_line_a
> > ...
> > here_comes_line_b
> > ...
> >
> > Furthermore, in my file, line_a and line_b only occur once.
> >
> > What code should I use?
>
> Either use an array to hold the whole file:
>
> awk '{file[NR]=$0} /here_comes_line_a|here_comes_line_b/{swap[++cnt]=NR}
> END{ tmp=file[swap[1]]; file[swap[1]]=file[swap[2]]; file[swap[2]]=tmp
> for (i=1;i<=NR;i++) print file[i] }' file
>
> or do two passes of the file:
>
> awk 'NR==FNR{ if (/here_comes_line_a/) a[NR]=$0
> else if (/here_comes_line_b/) b[NR]=$0
> next
> }
> NR in a { $0 = b[NR] }
> NR in b { $0 = a[NR] }
> 1' file file
>
> Both untested.

Or, in one pass, store just line_b and the intermediate lines:

awk '
BEGIN { lineb = ""; counter = 0 }
/here_comes_line_b/ { lineb = $0; next }
/here_comes_line_a/ {
print
for (i = 1; i <= counter; i++) {print store[i]}
print lineb
lineb = ""
next
}
lineb != "" { store[++counter] = $0; next }
1 {print}
' file


--
Glenn Jackman
Write a wise saying and your name will live forever. -- Anonymous
From: Rakesh Sharma on
On Nov 24, 2:34 pm, Hongyi Zhao <hongyi.z...(a)gmail.com> wrote:
> Hi all,
>
> I want to swap the appearance order of two lines in a file if needed.
> For detail, please see the following minimal example:
>
> ...
> here_comes_line_b
> ...
> here_comes_line_a
> ...
>
> Suppose the following should be the final result I want:
>
> ...
> here_comes_line_a
> ...
> here_comes_line_b
> ...
>
> Furthermore, in my file, line_a and line_b only occur once.
>
> What code should I use?
> --
> .: Hongyi Zhao [ hongyi.zhao AT gmail.com ] Free as in Freedom :.


Provided there's atleast one line between line_a & line_b we can do
this:

sed -e '
/\n/b
/re1/,/re2/!b
/re2/!H;/re1/h;/re2/!d
p;g;s/\n.*//;H;g;D
' yourfile