Как я ищу строки в файле, которые только содержат символы ASCII и затем действуют на них?

У меня есть текстовый файл, который похож на это:

English words only
English and 日本語
日本語のみ
English words only
English and 日本語
日本語のみ
English words only
Also English words only
English and 日本語
日本語のみ
English words only
English and 日本語
日本語のみ

Обратите внимание, что в середине там, существует две строки, English words only и Also English words only, одно право после другого.

То, что я должен сделать, проводят те две строки и объединение в одну строку, разделенную a /, как это:

English words only
English and 日本語
日本語のみ
English words only
English and 日本語
日本語のみ
English words only / Also English words only
English and 日本語
日本語のみ
English words only
English and 日本語
日本語のみ

Я нашел, что могу искать строки с символами ASCII со следующим регулярным выражением, [[:ascii:]], и для неASCII с [^[:ascii:]]. Однако я испытываю немного затруднений с помощью регулярных выражений для нахождения экземпляров не соответствия условию, начиная с того, на чем я должен искать, строки без символов неASCII.

Я нашел этот вопрос о "соответствии инверсии", но, ответы, там вне меня.

Затем конечно, это - другая проблема для соответствия строкам на основе их отношений друг к другу. Я могу соответствовать этим строкам, когда они один за другим? Я даже не уверен, что это возможно.

Существует ли способ, которым я могу искать все строки без символов неASCII и затем объединить их, с помощью LibreOffice, Gedit или командной строки?

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

6
задан 26 April 2018 в 09:54

2 ответа

Кажется, что можно использовать sed сделать это задание, даже при том, что это не знает о [[:ascii:]] класс символов. Вместо этого мы можем указать все символы ASCII с диапазоном escape-последовательностей [\d0-\d127], пока мы используем C или POSIX локали.

Вот команда, которая должна быть надежной:

LC_ALL=C sed -r ':a;N;s|^([\d0-\d127]+)\n([\d0-\d127]+)$|\1 / \2|;ta' file

Примечания

  • LC_ALL=C Использовать C настройки локали только для этой команды (иначе Вы получаете ошибку),
  • -r Используйте расширенный regex для создания команды более читаемой (нам нужно меньше обратных косых черт) (GNU sed также распознает -E с тем же значением).
  • :a Маркировка - цикл запускается здесь
  • ; Разделяет команды, как в оболочке
  • N Считайте следующую строку в пространство шаблона, таким образом, мы можем заменить \n
  • s|old|new| Замена old с new
  • ^([\d0-\d127])\n([\d0-\d127]+)$ - соответствуйте двум строкам только ASCII и получите первую строку в \1 и вторая строка в \2. ^ запуск строки, \n новая строка, и $ конец строки, таким образом, ^line 1\nline 2$ тесты весь line 1 и line 2.
  • \1 / \2 Первые и вторые строки, разделенные  / вместо новой строки.
  • ta - Если последняя команда поиска-и-замены, за которой следуют, выполните цикл снова. Это позволяет нам обрабатывать все строки файла, обрабатывая любые экземпляры, где существует больше чем две строки все-ASCII вместе.

Большое спасибо Eliah Kagan для показа меня, как использовать escape-последовательности для соответствия символам ASCII.

4
ответ дан 23 November 2019 в 07:37

Если Вы хотите целые строки, состоящие только из символов ASCII, необходимо привязать шаблон к запуску и концу строки, например, с grep

$ grep -P '^[[:ascii:]]*$' file
English words only
English words only
English words only
Also English words only
English words only

Некоторые инструменты обеспечивают флаг целой строки, такой как grep's -x или --line-regexp:

   -x, --line-regexp
          Select  only  those  matches  that exactly match the whole line.
          For a regular expression pattern, this  is  like  parenthesizing
          the pattern and then surrounding it with ^ and $.

разрешение Вам использовать:

$ grep -Px '[[:ascii:]]*' file
English words only
English words only
English words only
Also English words only
English words only

Мультилиния, соответствующая, добавляет целый другой слой сложности, так как многие общие утилиты обработки текста командной строки являются базирующейся строкой. Можно вызвать grep хлебать целый файл с помощью -Z отметьте однако существуют инструменты такой как pcregrep или perl самостоятельно являются, вероятно, более соответствующими в той точке.

Следующий выпуск, который необходимо решить, - то, как интерпретировать понятия, "запускаются строки" и "конца строки" в контексте многострочного соответствия. Некоторые инструменты обеспечивают флаги для который, как описано в Учебном руководстве Regex: Привязки: perl один из них, который обеспечивает a /m модификатор. Все еще необходимо хлебать файл путем сбрасывания разделителя записей по умолчанию (сделанный сюда использование -0777); например,

$ perl -0777 -pe 's{^([[:ascii:]]+)\n([[:ascii:]]+)$}{$1 / $2}mg' file
English words only
English and 日本語
日本語のみ
English words only
English and 日本語
日本語のみ
English words only / Also English words only
English and 日本語
日本語のみ
English words only
English and 日本語
日本語のみ
4
ответ дан 23 November 2019 в 07:37

Другие вопросы по тегам:

Похожие вопросы: