#regex #bash #text #sed
#регулярное выражение #bash #текст #sed
Вопрос:
Вот вывод из less
:
487451
487450<A3><BA>1<A3><BA>1
487449<A3><BA>1<A3><BA>1
487448<A3><BA>1<A3><BA>1
487447<A3><BA>1<A3><BA>1
487446<A3><BA>1<A3><BA>1
487445<A3><BA>1<A3><BA>1
484300<A3><BA>1<A3><BA>1
484299<A3><BA>1<A3><BA>1
484297<A3><BA>1<A3><BA>1
484296<A3><BA>1<A3><BA>1
484295<A3><BA>1<A3><BA>1
484294<A3><BA>1<A3><BA>1
484293<A3><BA>1<A3><BA>1
483496
483495
483494
483493
483492
483491
Я вижу здесь кучу непечатаемых символов. Как мне удалить их с помощью sed
/ tr
?
Моя попытка была 's/([0-9][0-9]*)/1/g'
, но это не сработало.
РЕДАКТИРОВАТЬ: Хорошо, давайте пройдемся дальше по исходному коду. Числа извлекаются из этого файла:
487451"><img src="Manage/pic/20100901/Adidas running-429.JPG" alt="Adidas running-429" height="120" border="0" class="BK01" onload='javascript:if(this.width>160){this.width=160}' /></a></td>
487450"><img src="Manage/pic/20100901/Adidas fs 1<A3><BA>1-060.JPG" alt="Adidas fs 1<A3><BA>1-060" height="120" border="0" class="BK01" onload='javascript:if(this.width>160){this.width=160}' /></a></td>
Первая строка совершенно нормальная, как и большинство строк. Второе «повреждено». Я бы просто хотел извлечь число в начале (используя 's/([0-9][0-9]*).*/1/g'
, но каким-то образом непечатаемые значения попадают в регулярное выражение, которое должно заканчиваться на "
.
ПРАВКА II: Вот уточнение: в текстовом файле нет скобок.Это символьные коды непечатаемых символов. Скобки там потому, что я скопировал файл из less
. Терминал Mac, с другой стороны, использует ??
для представления таких символов. Бьюсь об заклад, xterm
на моей Ubuntu напечатали бы этот белый овал со знаком вопроса.
Комментарии:
1. Вы хотите удалить
<A3>
в выходных данных или просто хотите заменить это на3
?2. Я хочу удалить все после первых шести цифр (только здесь их шесть, в реальном файле они различаются).
3. Хорошо, я опубликовал свой ответ ниже. Пожалуйста, попробуйте и дайте мне знать.
4. Это самое замечательное руководство, если вы когда-либо захотите использовать регулярное выражение unix: tutorialspoint.com/unix/unix-regular-expressions.htm
Ответ №1:
Классическая задача для sed
или Unix tr
команды.
sed 's/[^0-9]//g' $file
(Все, что не является цифрой — или новой строкой — удаляется.)
tr -cd '0-912' < $file > $file.1
Удалите ( -d
) дополнение ( -c
) цифр и новой строки…
Комментарии:
1. Я уже пробовал это,
tr
и это дает мнеtr: Illegal byte sequence
. Я не думаю, что он хочет читать непечатаемые файлы.2. Тогда вы, должно быть, работаете в языковом стандарте UTF-8 (или чем-то подобном), но читаете файл 8859-1. Данные неверны в формате UTF-8, поэтому вы не можете обработать их с использованием языкового стандарта UTF-8, установленного с помощью программ, которые знают о языковом стандарте. Это является источником раздражения для всех заинтересованных сторон. Простейшим обходным путем может быть установка LANG= C в среде и проверка, достаточно ли этого. Этого может быть недостаточно; возможно, вам придется установить LC_CTYPE (или LC_ALL) на что-то, что использует 8859-1 вместо этого.
Ответ №2:
Вы пропустили бит, где вы сопоставляете остальную часть строки.
sed 's/([0-9][0-9]*)[^0-9]*/1/g'
^^^^^^^
Ответ №3:
Попробуйте эту команду sed:
sed 's/^([0-9][0-9]*).*$/1/' file.txt
ВЫВОД (выполнение вышеуказанной команды для предоставленного вами входного файла)
487451
487450
487449
487448
487447
487446
487445
484300
484299
484297
484296
484295
484294
484293
483496
483495
483494
483493
483492
483491
Комментарии:
1. Нет, никаких изменений, (проверено
diff
ingod
s). 🙁2. @Mike: Я также предоставил вам свой вывод из вышеупомянутой команды sed. Это не то, что вы ожидаете получить на выходе? И я тестировал это как на Linux, так и на Mac.
Ответ №4:
Если вы знаете, что мусор всегда будет внутри скобок, почему бы не удалить этот мусор?
sed 's/<[^>]*>//g'
РЕДАКТИРОВАТЬ: Спасибо, Майк, это имеет смысл. В таком случае, как насчет:
sed 's/([0-9] ).*/1/g'
Комментарии:
1. Я почти уверен, что скобки — это просто способ less представлять непечатаемые символы.
Ответ №5:
Если данные всегда похожи на образец, удаление от менее чем до конца строки будет работать нормально. файл sed -i «s/<.*$//»
Комментарии:
1. Пожалуйста, перечитайте вопрос. В файле не должно быть символа меньше.