Grep строки с определенным количеством символов, включая разрыв строки - PullRequest
0 голосов
/ 31 октября 2018

Мне нужно grep только строки определенной длины, но также , включая перевод строки / перевод строки. Поэтому первая строка будет на один символ длиннее другой.

Пример:

"Random text with certain length\n"
"Random text with certain length"
EOF

Я использовал grep следующим образом:

grep -E "^.{length}$"

В результате печатаются обе строки, так как они имеют одинаковое количество символов, поскольку \ n не считается символом

Спасибо за любые идеи.

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

TL; DR

Для меня самый простой способ получить предлагаемые результаты - заменить символы новой строки на sed, прежде чем отправлять в grep (т.е. свернуть). Затем разверните при необходимости.

$ echo -e '"Random text with certain length\n"\n"Random text with certain length"\n' | sed -e ':a;N;$!ba;s/\n"/+"/g' -e '/"+/s//"\n/g' | grep -E "^.{33}$"
"Random text with certain length"
$ echo -e '"Random text with certain length\n"\n"Random text with certain length"\n' | sed -e ':a;N;$!ba;s/\n"/+"/g' -e '/"+/s//"\n/g' | grep -E "^.{34}$"
"Random text with certain length+"
$ echo -e '"Random text with certain length\n"\n"Random text with certain length"\n' | sed -e ':a;N;$!ba;s/\n"/+"/g' -e '/"+/s//"\n/g' | grep -E "^.{34}$" | sed -e '/+"/s//\n"/g'
"Random text with certain length
"

Спасибо за разъяснение описания. Часть из того, что следует, была со ссылкой на предыдущее описание, но, кажется, это пустая трата ...

Я не уверен, что полностью понимаю и сделал некоторые предположения.

  1. Все строки имеют двойные кавычки или, по крайней мере, что-то уникальное, чтобы складывать / разворачивать строки, которые вы хотите считать.
  2. Либо CR + LF, либо только LF - это то, что считается «новой строкой / переводом строки»
  3. В описании \ n (LF / $) может означать \ r (CR / ^ M). Это работает со ссылкой на wc. В противном случае grep и wc не будут считать строки одинаковой длины.

Другими словами, как указано, по умолчанию grep не считает символ новой строки (\ n) как символ, но считает возврат каретки (\ r), тогда как wc считает оба символа.

Это подтверждает \ n = перевод строки ($) и \ r = возврат каретки (^ M)

\ n = новая строка

$ echo -en '\n' | wc -c
1
$ echo -en '\n' | grep -E "^.{1}" | wc -c
0

\ r = возврат каретки

$ echo -en '\r' | wc -c
1
$ echo -en '\r' | grep -E "^.{1}" | wc -c
2

К grep возврат каретки является дополнительным символом. Новых строк нет.

Это даст одинаковое количество символов и результат для обеих строк.

echo -en '\n' | sed -e '/\r/s///g' | grep -E "^.{1}" | wc -c
0
echo -en '\r' | sed -e '/\r/s///g' | grep -E "^.{1}" | wc -c
0

Учитывая критерии фильтрации по длине строки, сама по себе grep -E никогда не будет считать символ новой строки / LF как символ и, следовательно, не может это сделать. Другой пример, где обе строки визуально одинаковой длины, но на самом деле одинаковой длины ...

$ echo -e 'hello\r\nworld\n'
hello
world
$ cat <<< "$(echo -e 'hello\r\nworld\n' | grep -E "^.{5}$")"
world
$ cat <<< "$(echo -e 'hello\r\nworld\n' | grep -E "^.{6}$")"
hello

... и вставка sed в конвейер, обе линии имеют одинаковую длину {5}:

$ cat <<< "$(echo -e 'hello\r\nworld\n' | sed -e '/\r/s///g' | grep -E "^.{5}$")"
hello
world
$ cat <<< "$(echo -e 'hello\r\nworld\n' | sed -e '/\r/s///g' | grep -E "^.{6}$")"
<no output>
0 голосов
/ 31 октября 2018

Если у вас есть содержимое, сохраненное в файл с именем file.txt, то вы можете попробовать что-то вроде этого:

cat file.txt | awk 'length($0) > 38

выводит только строку длиной более 38 символов:

"Random text with certain length\n" <br>

Если вы делаете:

cat a.txt | awk 'length($0) > 37'

, тогда отображаются обе строки, так как все они имеют 37 символов ...

Не уверен, если это то, что вы хотели в первую очередь ... Попробуйте в любом случае!

...