1

1. Summary

I don't understand, how I can sort lines in some places of file, not in all file.

It would be nice, if would be possible solve this task any gratis method.


2. Settings

1. File structure

I have a big (19 MB) file SashaMillionaire.md, has questions of one game. It consists of repeating blocks. Each block has a 10 lines. Structure of file (using PCRE regular expressions)

Millionaire
\d{18}
QUESTION.*
.*
.*
.*
.*
.*
.*
.*
Millionaire
\d{18}
QUESTION.*
.*
.*
.*
.*
.*
.*
.*

SashaMillionaire.md doesn't have another lines and text besides 10-lines blocks. It doesn't have blank lines and blocks with a greater or lesser number of lines than 10.

2. Example content of file

Millionaire
123456788763237476
QUESTION|2402394827049882049
Who is the greatest Goddess in the world?
Sasha
Kristina
Sasha
Katya
Valeria
AuthorOfQuestion
Millionaire
459385734954395394
QUESTION|9845495845948594999
Where Sasha live?
Novgorod
St. Petersburg
Kazan
Novgorod
Chistopol
Another author
Millionaire
903034225025025568
QUESTION|ABC121980850540445C
Another question.
Katya
Sasha
Kazan
Chistopol
Katya
Unknown author

3. Expected behavior

I need alphabetically sort lines 6—9, then sort 16—19, 26—29 and so on.

    but no sort another lines.

Example

The result should be this:

Millionaire
123456788763237476
QUESTION|2402394827049882049
Who is the greatest Goddess of the world?
Sasha
Katya
Kristina
Sasha
Valeria
AuthorOfQuestion
Millionaire
459385734954395394
QUESTION|9845495845948594999
Where Sasha live?
Novgorod
Chistopol
Kazan
Novgorod
St. Petersburg
Another author
Millionaire
903034225025025568
QUESTION|ABC121980850540445C
Another question.
Katya
Chistopol
Katya
Sasha
Kazan
Unknown author

4. Did not help

  1. Googling
  2. I find, that Unix commands sort, sed and awk can solve similar tasks, but I don't find, how I can solve my task use these commands.
3

Assuming each section starts with text Millionaire, you should be able to do this with vim/ex - either interactively, or scripted for example like so:

$ ex SashaMillionaire.md << 'EOF'
:g/^Millionaire$/+5,+8 sort
:1,$p
:q
EOF

Millionaire
123456788763237476
QUESTION|2402394827049882049
Who is the greatest Goddess in the world?
Саша
Валерия
Катя
Кристина
Саша
AuthorOfQuestion
Millionaire
459385734954395394
QUESTION|9845495845948594999
Where Sasha live?
Novgorod
Chistopol
Kazan
Novgorod
St. Petersburg
Another author
Millionaire
903034225025025568
QUESTION|ABC121980850540445C
Another question.
Katya
Chistopol
Katya
Kazan
Sasha
Unknown author

To modify the file in-place, replace print statement 1,$p by w

ex SashaMillionaire.md << 'EOF'
:g/^Millionaire$/+5,+8 sort
:wq
EOF

or, if you prefer a one-liner instead of a heredoc,

printf ':g/^Millionaire$/+5,+8 sort\nwq\n' | ex SashaMillionaire.md
  • Thanks for answer! It works for English symbols. But I have a bugs, if I have Cyrillic symbols. Example fileresult. My file contains Cyrillic, Latin symbols and numbers. Thanks. – Саша Черных Jun 28 '17 at 14:12
  • steeldriver, in your second variant (with partsort.sh file) output repeat for me 3 times... Thanks. – Саша Черных Jun 28 '17 at 15:56
  • steeldriver: not for Cygwin... I don't find, how I can correct set it. – Саша Черных Jun 28 '17 at 16:14
  • @СашаЧерных please see modified answer - the previous one was largely erroneous (it was doing the right thing - but on files saved from a previous run of the split command) – steeldriver Jun 28 '17 at 20:48
1

With awk, you could do something like:

awk '
  $0 == "Millionaire" {
    if (n < 0) {
      close("sort")
      print last
    }
    n = 4
  }
  n > 0 {
    n--
    print
    next
  }
  n-- {print last | "sort"}
  {last = $0}
  END {
    if (n < 0) {
      close("sort")
      print last
    }
  }'

To sort the lines from the fourth after Millionaire to the second before the next Millionaire.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.