Используйте sed для поиска и сохранения только строк с двумя альфа-символами в них

У меня есть файл со многими строками вроде этих

33B87401 33B87402 33B87403 33B8EE44 33B87405 33B87406 33B87407 33B87408 33B87409 33B8740A 33B8740B 33B8740C 33B87D0D 33B8740E 33B8740F 33B87410 33B87411 33B87C1E 33B87CC3 33B87C1C 

Я ищу способ сохранить только строки, содержащие только 2 альфа-символа

выход для этого примера будет

 33B8740A 33B8740B 33B8740C 33B8740E 33B8740F 

вот еще один список

 8765C3E3 8765C3E4 8765C3E5 8765C3E6 8765C3E7 8765C3E8 8765C3E9 8765C3EA 8765C3EB 8765C3EC 8765C3ED 8765C3EE 8765C3EF 8765C3F0 

Прочитайте много примеров sed и awk, и non может воспроизвести это.

спасибо

  • команда sed unterminated `s
  • Как обмениваться словами в имени файла с помощью оболочки?
  • Sed: удалить между первыми n строками те, у которых заданная строка в них
  • Sed: Заменить N первых вхождений персонажа
  • Regex не соответствует
  • Слияние дублированных строк, которые имеют одинаковые первые три поля
  • sed / awk заменяет определенный шаблон под другим шаблоном
  • умножение каждой строки
  • 6 Solutions collect form web for “Используйте sed для поиска и сохранения только строк с двумя альфа-символами в них”

     sed -ne's/[[:alpha:]]//3;t' -e's//&/2p' <in >out 

    … будет s/// исключить третье вхождение в строке любого символа в классе [[:alpha:]] . Это после того, как эта замена была успешной, и, если это так, выходит из сценария.

    Поскольку sed проинструктирован -n autoprint, строки ввода с тремя или более алфавитными символами в данный момент эффективно удаляются из вывода, и единственными входными строками, оставшимися для второго оператора s/// ubstitution, являются те, у которых два или меньше буквенных символов ,

    Вторая подстановка использует пустое // регулярное выражение с левой стороны – которое для sed (более эффективно) относится к самому последнему скомпилированному / regexp / – и поэтому может быть прочитано как s/[[:alpha:]]/... еще раз. Это попытка s/// включить второе вхождение алфавитного символа в строке для самого & и, как таковое, приводит к эффективному noop и никаких фактических изменений в строке. Однако, если он может это сделать, то строка также выводится на вывод.

    В итоге – первая s/// ubstitution эффективно удаляет из вывода все входные строки, которые соответствуют трем или более буквенным символам, а вторая подстановка p остатков для вывода только тех, которые соответствуют двум алфавитам.

    … w / grep

     grep -xE '([0-9]*[[:alpha:]]){2}' <in >out 

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

    Чтобы сделать так, как просили, хотя:

     grep -xE '([^[:alpha:]]*[[:alpha:]]){2}[^[:alpha:]]*' 

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

    grep обоих случаях используется переключатель -x grep . Однако любой из этих операторов мог бы обойтись, если бы привязки «head-of-line» и « $ tail-of-line» были (pre | ap) перенесены в regexp соответственно. Переключатель -x обозначает целочисленное совпадение – и поэтому регулярное выражение должно описывать все согласованные входные строки целиком, от головы до хвоста.

    Я бы использовал perl :

     perl -ne 'print if length s/\d//gr == 2' 

    Что использует:

    • -n для неявного переноса while ( <> ) { loop
    • s///r возвращает замененный текст, но не изменяет оригинал.
    • поэтому мы удаляем любые цифры, затем смотрим на длину строки
    • и напечатать строку, если это 2.

    Примечание: это удаляет цифры из ваших строк, оставляя цифры без цифр. Вместо этого вы можете использовать [^AZ] .

    Или, наоборот, если это понятно:

     perl -ne 'print if (()=m/([AZ])/g) == 2' 

    Это будет работать со старым perl который не поддерживает флаг r . Он использует сопоставление регулярных выражений для выбора текста и подсчет количества элементов массива (совпадений). И если это 2, печатает строку.

    Я просто написал простой скрипт python, который делает именно то, что вам нужно, я тестировал его на вашем входе, он отлично работает.

      #!/usr/bin/python def count_letters(input): count=0 for char in input: if char.isalpha(): count += 1 return count fh=open('test_input','r') for line in fh.readlines(): if count_letters(line) == 2 : print line 

    Что-то вроде строк:

    grep '^[0-9]*[AF][0-9]*[AF][0-9]*$'

    должен сделать трюк.

    Это означает, что шаблон, начинающийся в начале строки, имеет некоторые (возможно, нет) цифры, букву, больше цифр, другую букву и больше цифр до конца строки. Якоря критически важны, иначе вы получите все строки с двумя или более буквами.

    С awk

     awk '{x=$0; gsub(/[^[:alpha:]]/, "", x)};length(x) == 2' file 

    Это устанавливает каждую строку в переменную x за которой следует замена всех не-альфа-символов в x пустой строкой. Если длина модифицированного таким образом x равна 2 , соответствующая строка

    Альтернативно, с grep

     grep '^[^[:alpha:]]*[:[:alpha:]][^[:alpha:]]*[:[:alpha:]][^[:alpha:]]*$' file 

    С grep :

     LC_ALL=C grep -E '^([^[:upper:]]*[[:upper:]]){2}[^[:upper:]]*$' file.txt 

    Пример:

     % cat file.txt 33B87401 33B87402 33B87403 33B8EE44 33B87405 33B87406 33B87407 33B87408 33B87409 33B8740A 33B8740B 33B8740C 33B87D0D 33B8740E 33B8740F 33B87410 33B87411 33B87C1E 33B87CC3 33B87C1C % LC_ALL=C grep -E '^([^[:upper:]]*[[:upper:]]){2}[^[:upper:]]*$' file.txt 33B8740A 33B8740B 33B8740C 33B8740E 33B8740F 
    Interesting Posts

    Netflix работает с хромом, но не с хромом?

    Могу ли я контролировать количество TCP-соединений в секунду в curl?

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

    Избегайте буферизации вывода для группы команд (фигурные скобки) в сценарии bash

    Замечания Strip #xxx, за исключением случаев, когда они встречаются внутри кавычек в sed

    Заставить GRUB загрузиться в определенное ядро ​​/ ОС?

    Разрешить setuid для сценариев оболочки

    Выход из командной строки Memoizing / caching

    Что означает символ «-» в Linux?

    Надежный источник RPM для CentOS?

    Wget: ошибка сегментации (сбрасывание ядра)

    Как переместить все файлы плюс скрытые в папку вниз?

    Как заменить последнее совпадение на строку

    Убить фоновый SSH при выходе оболочки

    Использование Evince вместо Okular для Alpine (настройка MIME для просмотра PDF-файлов)

    Linux и Unix - лучшая ОС в мире.