我在 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)
有什么问题?如何删除空白行?
答案1
假设您不仅想删除空行,还想删除仅包含空格字符的行。为此,请使用:
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)
答案2
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
,因为我们使用的是基本正则表达式,并且[[:blank:]]
是POSIX 字符类,因此它是可移植的。
我们也可以在 Python 中做类似的事情,但不使用正则表达式:
$ 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
dos2unix
可能首先使用专门为将 DOS 文件转换为 Unix 文件而设计的实用程序,然后使用sed
和,这样会更简单grep
。请参阅ByteCommander 的回答这显示了如何做到这一点的示例。
答案3
使用
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'
答案4
这个 grep 命令可以正常工作,甚至可以解释 dos 回车符、空白行、空行以及包含空格和/或制表符的空白行:
grep -v '^[[:space:]]*$'