如何从文本文件中删除包含特定字符串的所有行

如何从文本文件中删除包含特定字符串的所有行

技术背景

在系统运维和文件处理过程中,经常需要从文本文件中删除包含特定字符串的行。这在清理日志文件、处理配置文件等场景中非常常见。不同的工具和方法可以实现这一目的,下面将详细介绍各种实现方式。

实现步骤

使用 sed

  • 打印输出到标准输出
1
sed '/pattern to match/d' ./infile
  • 直接修改文件(GNU sed)
1
sed -i '/pattern to match/d' ./infile
  • 直接修改文件(BSD sed,如 Mac OS X 和 FreeBSD)
1
sed -i '' '/pattern to match/d' ./infile
  • 直接修改文件并创建备份(BSD 和 GNU sed)
1
sed -i.bak '/pattern to match/d' ./infile

使用 AWK

1
awk '!/pattern/' file > temp && mv temp file

使用 Ruby (1.9+)

1
ruby -i.bak -ne 'print if not /test/' file

使用 Perl

1
perl -ni.bak -e "print unless /pattern/" file

使用 Shell (bash 3.2 及以后)

1
2
3
4
5
while read -r line
do
[[ ! $line =~ pattern ]] && echo "$line"
done <file > o
mv o file

使用 GNU grep

1
grep -v "pattern" file > temp && mv temp file

使用 ex

1
ex +g/match/d -cwq file

使用 vim

1
:g/<pattern>/d

使用 ed

1
printf "%s\n" "g/pattern/d" w | ed -s filename

或者使用 heredoc:

1
2
3
4
ed -s filename <<EOF
g/pattern/d
w
EOF

核心代码

以下是一些核心代码示例:

sed 示例

1
2
# 删除包含特定字符串的行并直接修改文件
sed -i '/pattern/d' filename

grep 示例

1
2
3
4
# 打印不包含特定字符串的行
grep -v 'pattern' filename
# 直接修改文件
echo "$(grep -v "pattern" filename)" >filename

Perl 示例

1
2
# 直接修改文件并保留备份
perl -i.bk -nle'/regexp/||print' file1 file2 file3

最佳实践

  • 性能方面:根据测试,在处理约 345000 行的文件时,grep 方法比 sed 方法快约 15 倍。示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
time sed -i "/CDGA_00004.pdbqt.gz.tar/d" /tmp/input.txt
# real 0m0.711s
# user 0m0.179s
# sys 0m0.530s

time perl -ni -e 'print unless /CDGA_00004.pdbqt.gz.tar/' /tmp/input.txt
# real 0m0.105s
# user 0m0.088s
# sys 0m0.016s

time (grep -v CDGA_00004.pdbqt.gz.tar /tmp/input.txt > /tmp/input.tmp; mv /tmp/input.tmp /tmp/input.txt )
# real 0m0.046s
# user 0m0.014s
# sys 0m0.019s
  • 精确匹配:如果需要精确匹配字符串,可以使用 grep-w 标志。例如,要删除包含数字 11 的行,但保留包含 111 的行:
1
grep -w -v "11" file

常见问题

  • sed 兼容性问题sed-i 选项在不同系统(如 GNU sed 和 BSD sed)中用法不同。GNU sed 可以直接使用 -i 进行原地修改,而 BSD sed 需要 -i ''
  • 变量替换问题:在使用 sed 进行变量替换时,需要使用双引号。例如:
1
sed -i '' "/$pattern/d" $file
  • 字符串转正则问题:如果要将任意字符串转换为正则表达式,可以使用以下方法:
1
2
re=$(sed 's/\([\[({.*+^$?]\)/\\\1/g' <<< "$STRING")
sed "/$re/d" FILE

如何从文本文件中删除包含特定字符串的所有行
https://119291.xyz/posts/2025-05-15.how-to-delete-lines-containing-specific-string-from-text-file/
作者
ww
发布于
2025年5月15日
许可协议