У меня есть такой файл с несколькими пустыми строками в vscode
$ tail -n 20 draft3.py
hi = len(a)
if lo < 0:
raise ValueError('low must be non-negative')
if lo == hi:
return None
mid = (lo + hi) // 2
if x == a[mid]:
return x
if x > a[mid]:
lo = mid + 1
return self.bi_search(a, x, lo, hi)
if x < a[mid]:
hi = mid
return self.bi_search(a, x, lo, hi)
Попробованный несколько методов для удаления пустых строк
'grep-v-e '^ $' перестал работать
$ tail -n 20 draft3.py | grep -v -e '^$'
hi = len(a)
if lo < 0:
raise ValueError('low must be non-negative')
if lo == hi:
return None
mid = (lo + hi) // 2
if x == a[mid]:
return x
if x > a[mid]:
lo = mid + 1
return self.bi_search(a, x, lo, hi)
if x < a[mid]:
hi = mid
return self.bi_search(a, x, lo, hi)
'grep-Ev "^ $" перестал работать
$ tail -n 20 draft3.py | grep -Ev "^$"
hi = len(a)
if lo < 0:
raise ValueError('low must be non-negative')
if lo == hi:
return None
mid = (lo + hi) // 2
if x == a[mid]:
return x
if x > a[mid]:
lo = mid + 1
return self.bi_search(a, x, lo, hi)
if x < a[mid]:
hi = mid
return self.bi_search(a, x, lo, hi)
'sed '/^ $/d' перестал работать
$ tail -n 20 draft3.py | sed '/^$/d'
hi = len(a)
if lo < 0:
raise ValueError('low must be non-negative')
if lo == hi:
return None
mid = (lo + hi) // 2
if x == a[mid]:
return x
if x > a[mid]:
lo = mid + 1
return self.bi_search(a, x, lo, hi)
if x < a[mid]:
hi = mid
return self.bi_search(a, x, lo, hi)
В чем проблема? Как мог удалить пустые строки?
grep -v '^$'
удалит пустые строки. Но что, если у нас есть пробелы или вкладки в некоторых строках? Например, я добавил 3 пробелов к частям Вашего текста, и если мы делаем cat -A
мы будем видеть, что это показывает разделитель строки $
, но это будет смещено.
$
mid = (lo + hi) // 2$
$
if x == a[mid]:$
return x$
if x > a[mid]:$
Вторая строка там имеет 3 пробелов, сначала каждый не делает. Таким образом, мы также хотим использовать [[:blank:]]
класс символов для составления их также:
$ grep -v '^[[:blank:]]*$' text.txt
hi = len(a)
if lo < 0:
raise ValueError('low must be non-negative')
if lo == hi:
return None
mid = (lo + hi) // 2
if x == a[mid]:
return x
if x > a[mid]:
lo = mid + 1
return self.bi_search(a, x, lo, hi)
if x < a[mid]:
hi = mid
return self.bi_search(a, x, lo, hi)
Теперь необходимо видеть, что строки с 3 добавленными пробелами не стало. *
показывает нуль или больше повторений символов, таким образом, шаблон ^[[:blank:]]*$
также подразумевает ^$
когда существует нулевой пробел или символы табуляции на строке. Таким образом, этот шаблон обрабатывает и действительно пустые и на вид пустые строки. Это также применяет точно то же к grep
или sed
, потому что мы используем основные regex выражения и [[:blank:]]
один из классов символов POSIX, таким образом, это портативно.
Мы могли также сделать что-то вроде этого в Python, но без regex шаблонов:
$ python3 -c 'import sys; print("\n".join([ l.rstrip() for l in sys.stdin if l.strip().split() ]))' < text.txt
hi = len(a)
if lo < 0:
raise ValueError('low must be non-negative')
if lo == hi:
return None
mid = (lo + hi) // 2
if x == a[mid]:
return x
if x > a[mid]:
lo = mid + 1
return self.bi_search(a, x, lo, hi)
if x < a[mid]:
hi = mid
return self.bi_search(a, x, lo, hi)
Почему это работает? Поскольку .split()
на строке разделит в пробелах для извлечения непробельных маркеров. Если строка содержит только пробелы, получающийся список от .split()
будет пусто.
Как отмечено ilkkachu в комментариях, проблема может также произойти при использовании окончаний строки CRLF (используемый в текстовых файлах DOS/Windows). Легко видеть, использует ли файл окончания строки CRLF через cat -A
, они будут отмечены как ^M
. Например,
$ printf 'hello\n\r\nWorld\n \r\ntest\n\nnewtest\n' | cat -A
hello$
^M$
World$
^M$
test$
$
newtest$
Одна вещь, которая могла быть сделана для составления возврата каретки, является этим:
$ printf 'hello\n\r\nWorld\n \ntest\n\nnewtest\n' | sed '/^[[:blank:]]*\r*$/d'
hello
World
test
newtest
Может быть более просто сначала использовать a dos2unix
утилита, специально разработанная для преобразования файлов DOS в файлы Unix, и затем, использует sed
и grep
. См. ответ ByteCommander, который показывает пример того, как сделать это.
По-видимому, Вы хотите удалить не только пустые строки, но также и строки только с пробельными символами. Для этого используйте:
sed '/^\s*$/d' # or respectively
grep -v '^\s*$'
sed
выражение d
элиты каждая строка с любым числом (*
) из пробельных символов (\s
) в нем. grep -v
производят любая строка, которая не соответствует выражению.
$ sed '/^\s*$/d' <draft3.py
hi = len(a)
if lo < 0:
raise ValueError('low must be non-negative')
if lo == hi:
return None
mid = (lo + hi) // 2
if x == a[mid]:
return x
if x > a[mid]:
lo = mid + 1
return self.bi_search(a, x, lo, hi)
if x < a[mid]:
hi = mid
return self.bi_search(a, x, lo, hi)
использовать
perl -p -e 's/^[:blank:]*$//g' inputfile | sed '/^$/d'
и Вы будете иметь
tail -n 20 draft3.py
hi = len(a)
if lo < 0:
raise ValueError('low must be non-negative')
if lo == hi:
return None
mid = (lo + hi) // 2
if x == a[mid]:
return x
if x > a[mid]:
lo = mid + 1
return self.bi_search(a, x, lo, hi)
if x < a[mid]:
hi = mid
return self.bi_search(a, x, lo, hi)
Только с sed
sed -r 's/^[[:space:]]*$//g' inputfile | sed '/^$/d'