Сортировка строк в файле

Ранее мы уже писали различные скрипты для примера использования возможностей языка python, но не сказать, чтобы они были нужны в повседневности и могли претендовать на какое-то практическое применение. Сегодня же будет рассмотрен один очень небольшой и очень нужный (автору) скрипт. На его написание натолкнуло использование gentoo linux поэтому считаю, что он может быть небезынтересен пользователям этой операционной системы и прикрепляю соответствующий тег к посту.

В чём суть работы скрипта: он сортирует в алфавитном порядке записи в /etc/portage/*. При пополнении парка программ такие файлы как package.use, package.keywords и им подобные наполняются беспорядочными строками, в коих некоторое время спустя сложно найти что-то самому хозяину. Так расставим всё по местам!

Сначала приводится полный пример кода, содержащий менее двадцати строк, затем построчный разбор с комментариями.

# sort.py
#
#! /usr/bin/env python
# -*- coding: utf-8 -*-
package = input('Choose file for sort: ')
try:
    file = open(package, 'r+')
    pos = 0
    line = file.readlines()
    file.seek(pos)
    sort_text = sorted(line)
    for new_line in sort_text:
        file.write(new_line)
        pos = file.tell()
    file.close()
except IOError:
    print("No such file or directory. Repeat, please!")

Первая строка указывает на расположение интерпретатора python, вторая — на кодировку по-умолчанию.

Далее вводится переменная package, которой будет присвоено значение указанное пользователем. Иными словами при запуске команды sudo python sort.py будет запрошен путь к текстовому файлу, который в дальнейшем и подвергнется правке.

Весь следующий блок кода обёрнут инструкцией try-except, перехватывающей исключение IOError. Это нужно для проверки ввода пользовательских данных. Например, вы могли ошибиться при наборе пути к файлу или ввели число. В таком случае вам укажут на вашу ошибку.

  • file = open(package, 'r+') — открыть выбранный пользователем файл для обновления.
  • pos = 0 — установить позицию в начало
  • line = file.readlines() — построчное чтение из файла и присваивание переменной line получившегося списка
  • file.seek(pos) — перемещать позицию
  • sort_text = sorted(line) — получение нового отсортированного по алфавиту списка

В следующем блоке проводится обход списка, перезапись выбранного файла, возвращение текущей позиции, закрытие файла:

for new_line in sort_text:
    file.write(new_line)
    pos = file.tell()
    file.close()

Кроме того, можно проводить сортировку по ключу. Для этого достаточно создать дополнительную функцию. Например:

def sortByLenght(inputSrt):
    return len(inputSrt)

Теперь можно вызывать функцию sorted с ключом:

>>> new_list = sorted(old_list, key=sortByLenght)

Ещё немного теории или справка:

Файл может быть открыт в режимах только для чтения, для записи, для обновления.

  • f = open('file') — откроет файл только для чтения
  • f = open('file', 'r') — то же самое
  • 'w' — открытие файла для записи
  • 'a' — для добавления в конец
  • 'b' — указание на двоичные данные: 'wb', 'rb'.
  • 't' — явное указание на то, что файл текстовый. Обычно не пишется
  • 'w+' — открытие файла в режиме для обновления, в момент открытия файла его длина усекается до нуля, возможны чтение и запись
  • 'r+' — открытие файла в режиме для обновления, длина не усекается, возможны чтение и запись
  • метод readline() — читает одну строку, возвращает строку
  • метод readlines() — читает все строки из файла, возвращает список
  • метод tell() — возвращает текущую позицию в файле
  • метод seek() — перемещает текущую позицию в новое место
  • метод write() — запишет в файл одну строку
  • метод writelines() — запишет список строк