С чего начинается строка или ещё одна загадка bash'а...

CORPSE аватар

Как я раньше думал, строка должна начинаться, как и всё остальное - с начала. А нет, не тут-то было.
Пытался привязать своё gui для fping к скрипту поиска мака на коммутаторах, но тут столкнулся с проблемой - строки, получаемые с коммутаторов d-link (три последние) мешали мне жить:

$ cat test1 #содержимое файла
  233      00:17:9a:05:a5:be     g2    dynamic   
  233      00:17:9a:05:a5:be     g1    dynamic   
233   kesm              00-17-9A-05-A5-BE  24      Dynamic
233   kesm              00-17-9A-05-A5-BE  50      Dynamic
233   kesm              00-17-9A-05-A5-BE  5       Dynamic

$ cat test1 | awk '{ print $1 }' #печатаем первую колонку - всё чудно
233
233
233
233
233
$ cat test1 | awk '{ print $2" "$1 }' #а теперь печатаем сначала вторую колонку, а потом первую
00:17:9a:05:a5:be 233
00:17:9a:05:a5:be 233
233m 
233m 
233m 

#первая колонка, как видим, затирает вторую

Я долго мучался на предмет того, что с этим делать. В конце-концов поступил следующим образом: открыл файл с выводом в mcedit и посмотрел на него в HEX. Оказалось, что началу строк, в которых проблем нет, " 233" соответствует "20 20 32 33 33", два пробела и цифры 233. Окончанию строки соответствуют непечатаемые символы с кодами "0D 0A". А строка, в которой возникают проблемы начинается с последовательности "0D 0A 0D", следовательно, проблема кроется в лишнем символе с кодом "0D". Исходя из этого я сначала пытался заменить одну последовательность на другую, но это мне не удалось. В баше вообще-то можно оперировать символами по восьмеричному или шестнадцатеричному значению кода. В таком случае они будут представлены как \xHH или \nnn, где HH - шестнадцатеричный код, а nnn - восьмеричный.
Как показал опыт, удаление "0D" из всех строк, не сказывается на работоспособности. То есть, в качестве символа конца строки можно оставить просто 0A.

$ cat test1 | sed 's/\x0D//g'| awk '{ print $2" "$1 }'
00:17:9a:05:a5:be 233
00:17:9a:05:a5:be 233
kesm 233
kesm 233
kesm 233

Кстати, если кто-нибудь вспомнит о этом:

В UNIX окружении: преобразование окончания строк из формата DOS (CR/LF) в формат Unix (LF):
           sed 's/.$//' (подразумевается что все строки заканчиваются с CR/LF)
           sed 's/^M$//' (в bash/tcsh, нажмите Ctrl-V затем Ctrl-M)
           sed 's/\x0D$//' (работает в ssed, gsed 3.02.80 или выше)

то скажу сразу, что не работает, ибо удаляет "0D" только идущее перед "0A", а проблема кроется в символе 0D, который стоит в начале новой строки.

P.S.: Может быть кому-нибудь пригодится. :)

Grifon аватар

Это можешь проверить?

sed 's/\r//g'

0x0D --- это знаменитый символ возврата каретки, которому соответствует последовательность \r в языке Си.

конец текстовой строки в разных осях обозначают по разному.

В никсах принято для обозначения конца строки использовать только символ перевода строки \n с кодом 0x0A. Правда терминал или принтер должен быть настроен на работу с таким концом строки, иначе получится лесенка, когда следующая строка начинается с позиции, на которой закончилась предыдущая строка.

Другие оси используют для обозначения конца строки комбинацию символов перевода строки и возврата каретки. Причем встречаются обе возможные комбинации (правда одна занчительно реже чем другая).

Не совсем понятно, откуда у тебя взялся мусор в виде дополнительного символа возврата каретки. Скорее всего ты не совсем удачно снес пустые строки...

В принципе, символ возврата каретки иногда исползуют дла печати разных счетчиков, когда нужно новый текст вывести поверх старого... Но я очень сильно сомневаюсь, что в твоем случае будет такое использование.

Так что под никсами можешь смело сносить все символы возврата каретки, как посоветовал Grifon. Если же нужно сохранить конец строки в виде пары символов, то можно
попробовать

sed 's/^\r//' или sed 's/\r$//'

в зависимости от того, какая из комбинаций является правильной для конкретной оси...

ЗЫ: рекомендую поискать, где теряются символы \n

advokat аватар

лишний символ взялся из за значения колонок

1.как видим в одном файл в формате ASC соеденены две таблицы
при этом количество столбцов в них разное или заполнены они по разному
может здесь ответы от двух раз D-Linkов

CORPSE аватар

Скорее это действительно остаток от снесённых grep'ом лишних строк d-link'ов.

Вполне возможно, НО причем тут управляющий символ \r ?
Применений этому символу не так уж и много, и его не используют для разделения полей/столбцов...

CORPSE аватар

Тут надо спрашивать товарищей из D-Link скорее всего.

Мне почему-то кажется, что товарищи из D-Link скорее всего не причем :)

CORPSE аватар

Всем спасибо. Проверил, да, это действительно \r.

Grifon аватар

Ну тогда ещё мой один тычок. использовать sed и awk в одной связке - это масло масленное. Почему нельзя использовать функцию gensub в awk, я не понимаю.

CORPSE аватар

Хотя бы потому, что я до этого момента не подозревал о её существовании. :)
Уполз читать маны.

Настройки просмотра комментариев

Выберите нужный метод показа комментариев и нажмите "Сохранить установки".