I have a text file containing text data. I'd like to move all lines starting from XY: and OTP XY: to the top of the file. How can I do this in Bash using sed, awk, other?
-
Noting that bash is just a/your shell, and is not an editor. – Jeff Schaller♦ Sep 10 at 13:58
With GNU ed
(note: this modifies file
in place; to output the edited file to standard output instead change wq
to ,p q
):
printf '%s\n' 'g/^\(\|OTP \)XY:/m0' wq | ed -s file
Using grep
:
{ grep -E '^(OTP )?XY:' input_file; grep -E -v '^(OTP )?XY:' input_file; } > ouput_file
The 2 grep
commands filter the input_file
with an without (-v
) the wanted pattern.
The { ... } > output_file
stores both grep
output to a file.
-
It did work only for
OTP XY:
But I just realised that I need to move line starting from string and one line below. – Syn Romana Sep 3 at 19:02
Another approach might be to use awk
, for example:
awk -v re='^OTP XY:|^XY:' 'NR==FNR && $0 ~ re; NR!=FNR && $0 !~ re' file file
The above uses a single process, never stores more than a single line in memory, but does two passes on the file (it reads it twice).
If one of the two patterns is rather unlikely in the file, i.e. small enough to fit in ram, you could use something like this:
awk '/^OTP XY:|^XY:/{print;next} {a = $0 ORS a};END{printf "%s", a}' file
This also uses a single process, this time a single pass of the file is made, but the memory usage could increase quite a bit depending on size/contents of the file.
-
First line is moving only OTP XY: to the top, but without the one line below. The second line is not doing anything. – Syn Romana Sep 11 at 19:08
-
@SynRomana Could you edit your question to add samples of the input and expected outputs? I did some tests here and it seemed to work... – user000001 Sep 11 at 19:11
-
-
-
Sample input:
#DATA:-1,XY: AAA
random text
#DATA:-1,XY: AABB
random text
– Syn Romana Sep 12 at 20:09