Система Orphus
[]

четверг, 28 августа 2008 г.

Обработка текстов в *nix


Очень часто администраторам *nix-систем приходится выполнять различные выборки, сортировки, группировки неструктурированных данных. Благо система имеет уйму утилит для этого. Рассмотрим в примерах выборку определённых полей файла. Надо отобрать из файла данные размещённые в первой, пятой и шестой колонках файла /etc/passwd.


Существует множество решений, ниже приведены лишь несколько из них:

  1. cat /etc/passwd | awk -F\: '{print $1" "$5" "$6}'
    ...
    avahi Avahi mDNS daemon,,, /var/run/avahi-daemon
    haldaemon Hardware abstraction layer,,, /home/haldaemon
    ...
  2. cat /etc/passwd | awk -F\: '{print $1":"$5":"$6}'
    ...
    avahi:Avahi mDNS daemon,,,:/var/run/avahi-daemon
    haldaemon:Hardware abstraction layer,,,:/home/haldaemon
    ...
  3. cat /etc/passwd | cut -d":" -f1,5,6
    ...
    avahi:Avahi mDNS daemon,,,:/var/run/avahi-daemon
    haldaemon:Hardware abstraction layer,,,:/home/haldaemon
    ...
  4. cut -d":" -f1,5,6 /etc/passwd
    ...
    avahi:Avahi mDNS daemon,,,:/var/run/avahi-daemon
    haldaemon:Hardware abstraction layer,,,:/home/haldaemon
    ...

Чем отличаются друг от друга эти варианты?

Первые два варианта: 1 и 2, - используют cat и awk. Первая утилита выводит содержимое файла /etc/passwd, вторая отбирает необходимые поля. "-F:" указывает на то, что разделителем полей в потоке служит двоеточие. Обратный слэш () перед двоеточием предписывает читать двоеточие, как двоеточие и не пытаться обработать его, как спецсимвол. В общем-то, обратный слэш используется в данном случае для перестраховки. Обратите внимание, что в первом случае мы вывели поля (нумеруются начиная с 1), разделённые пробелом, а во втором - двоеточием. Если вам необходимо модифицировать вывод, используйте эту связку, если вам нужно просто вывести требуемые поля пользуйтесь вариантами три или четыре.

В третьем варианте используется связка cat и cut. Первый выводит, второй режет :) Эту связку можно можифицировать так, как указано в варианте 4, так как cut может принимать на вход и поток (вариант три), и файл (вариант четыре). -d":" - указывает считать разделителем полей двоеточие. Здесь разделитель указан в кавычках, поэтому использовать обратный слэш () нет необходимости. -f1,5,6 говорит о том, что нужно отобразить 1-ое, 5-ое и 6-ое поля. Имейте ввиду, что для cut порядок полей, пречисленных после -f, не имеет значения. Поля будут выводится так, как они расположены в файле. Другими словами, вы просто указываете какие поля вас интересуют, а не порядок вывода полей. Если вам необходимо изменить порядок полей, воспользуйтесь awk.Например, так:

cat /etc/passwd | awk -F\: '{print $6" "$5" "$1}'
...
/var/run/avahi-daemon Avahi mDNS daemon,,, avahi
/home/haldaemon Hardware abstraction layer,,, haldaemon
...

Кроме того, awk также умеет получать данные не только из потока, но и напрямую из файла. Т.е. последний пример мы можем переписать так:

awk -F\: '{print $6" "$5" "$1}' /etc/passwd
...
/var/run/avahi-daemon Avahi mDNS daemon,,, avahi
/home/haldaemon Hardware abstraction layer,,, haldaemon
...
Почему я чаще пользуюсь конструкцией "cat | awk" или "cat | cut"? Всё просто. Когда я пытаюсь отобрать поля, я не всегда помню их точное положение в файле. Тогда я делаю: cat /etc/passwd

Получаю полный список. После чего, уточнив нужные поля, нажимаю стрелочку вверх (в bash это вызов предыдущей команды) и дописываю | awk........

Мне так удобнее. Я не говорю, что так нужно делать всем. Но если кто-то решит, что способ, которым он пользовался до сих пор, хуже предложенного мною и станет пользоваться им, значит не так уж и плох мой способ. :)


Похожие статьи

2 коммент.:

Анонимный комментирует... четверг, 20 ноября 2008 г. в 22:41:00 GMT+2

в кавычки брать $1 в awk не надо
ps
cut команда которую я никак не запмню как использовать Ж:-)

Angel 2S2 комментирует... пятница, 21 ноября 2008 г. в 14:59:00 GMT+2

А $1 в кавычки не берется. Это пробел в кавычках.

Отправить комментарий