1

I have a txt file like this

AAAAAAAAAA BBBBBBBBBB CCCCCCCC DDDDDDDDDDD EEEEEEEEEEE FFFFFFFFFFF GGGGGGGGGGG HHHHHHHHHHH IIIIIIIIIII 

groups of 3 lines with a line feed between.

I want to invert the first two lines of each group, making the file like this

BBBBBBBBBB AAAAAAAAAA CCCCCCCC EEEEEEEEEEE DDDDDDDDDDD FFFFFFFFFFF HHHHHHHHHHH GGGGGGGGGGG IIIIIIIIIII 

how do I do that from terminal?

EDIT: I have uploaded a sample of my text file to here if you need to test your answer against it.

3 Answers 3

2
$ cat -n ip.txt 1 AAAAAAAAAA 2 BBBBBBBBBB 3 CCCCCCCC 4 5 DDDDDDDDDDD 6 EEEEEEEEEEE 7 FFFFFFFFFFF 8 9 GGGGGGGGGGG 10 HHHHHHHHHHH 11 IIIIIIIIIII 

Since it is a fixed format, use modulo operator accordingly

$ awk 'NR%4==1{s=$0; next} 1; NR%4==2{print s}' ip.txt BBBBBBBBBB AAAAAAAAAA CCCCCCCC EEEEEEEEEEE DDDDDDDDDDD FFFFFFFFFFF HHHHHHHHHHH GGGGGGGGGGG IIIIIIIIIII 


and a perl regex version for fun

perl -00 -pe 's/(\N+\n)(\N+\n)/$2$1/' ip.txt 
  • -00 paragraph mode, similar to awk's -v RS=
  • then interchange first two lines
    • can also use (\N+\n)((?1)) - useful if complicated regex needs to be repeated
3
  • for some reason both your answers go well up to a certain point of my text file and then stops... I am trying to discover why. If you want to try, here is a sample of my text file Commented Dec 16, 2017 at 16:15
  • discover the problem on my text file... your perl version is working for me. Thanks Commented Dec 16, 2017 at 16:21
  • I checked it, seems like you had space in some of the empty lines... but in that case, my awk version is correct because it doesn't rely on paragraphs.. and indeed when I checked, perl version gave wrong answer... Commented Dec 16, 2017 at 16:25
2

One way - with GNU awk:

gawk 'BEGIN{RS=""; OFS=FS="\n"} {tmp = $2; $2 = $1; $1 = tmp; ORS=RT} 1' file BBBBBBBBBB AAAAAAAAAA CCCCCCCC EEEEEEEEEEE DDDDDDDDDDD FFFFFFFFFFF HHHHHHHHHHH GGGGGGGGGGG IIIIIIIIIII 
7
  • Only awk works too. Commented Dec 16, 2017 at 15:47
  • @muhammad I guess it depends what you mean by "only awk" - the version of mawk that I have doesn't know about RT for example Commented Dec 16, 2017 at 15:51
  • for some reason your code messes with the spaces between the groups of lines... you can test it against a sample of my text file here Commented Dec 16, 2017 at 16:16
  • @SpaceDog what flavor and version of awk are you using? Commented Dec 16, 2017 at 16:21
  • 1
    @MiniMax the empty record separator trick is described here Multiple-Line Records (sometimes referred to as paragraph mode) Commented Dec 16, 2017 at 23:45
2
sed -n 'h; n; G; N; p; n; p' input.txt 

Explanation

The sed has two operational spaces - the hold space and the pattern space. They are like two variables - var_1 and var_2. The each input line goes into the pattern space, but you can copy (it replaces all content of the hold space) or append it to the hold space. Thus:

  • h - copies the pattern space to the hold space. Now, both the pattern and hold spaces are: AAAAA.
  • n - gets the next line of input into the pattern space. So, the pattern space is now: BBBBB.
  • G - appends a newline and the content of the hold space (AAAAA) to the pattern space so the pattern space is now BBBBB\nAAAAA.
  • N - appends a newline and the next line of input to the pattern space - BBBBB\nAAAAA\nCCCCC
  • p - prints the pattern space.
  • n - gets the next line of input into the pattern space, if it exists and exits otherwise (if the end of file was reached).
  • p - prints the pattern space again.

Output

BBBBBBBBBB AAAAAAAAAA CCCCCCCC EEEEEEEEEEE DDDDDDDDDDD FFFFFFFFFFF HHHHHHHHHHH GGGGGGGGGGG IIIIIIIIIII 
2
  • what magic is that? It would be great if you give us some explanation. Commented Dec 17, 2017 at 10:14
  • 1
    @muhammad Explanation added. Commented Dec 17, 2017 at 11:15

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.