如何从多个文件中删除特定字符串之前的所有行

19

我有n个文件,例如:

文件1:

1aaa
2eee

Test        XXX
Hanna
Lars 

文件2:

1fff
2ddd
3zzz

Test        XXX
Mike
Charly

我希望从所有 n 个文件中删除“Test XXX”之前的所有行,需要删除的行数因文件而异。

我的想法:

for file in 1 :n
do
pos=grep -n "Test XXX" file$file
sed -i "1:$pos-1 d" file$file >new$file
done

问题是什么? - stema
1
看起来是 https://dev59.com/R2025IYBdhLWcg3wkGx7 的重复。 - ErichBSchulz
4个回答

29
这对你应该有效:

这应该适合你:

sed -i '1,/Test XXX/d' file1
sed -i '1,/Test XXX/d' file2

或者简单地说

sed -i '1,/Test XXX/d' file*

3
小心,否则您将会丢失原始文件。 - Lynch
1
这正是-i(内联)选项的目的。 - ztank1013
7
如果您想同时创建一个备份文件,请使用“-i.bak”。 - l0b0
7
似乎这个回答与问题不同,问题是如何删除在特定行之前的行,不包括该特定行。 - Tim Harper
1
很不幸,这也会删除Test XXX这一行... : / - Jewenile
显示剩余5条评论

10

这将适用于您的示例,即使匹配模式位于第一行:

sed -n -E -e '/Text XXX/,$ p' input.txt | sed '1 d'
例如,如果您的输入很简单
Test        XXX
Mike
Charly

这将为您提供

Mike
Charly

如果你想保留第一个匹配项 Test XXX,那么只需使用:

sed -n -E -e '/Text XXX/,$ p' input.txt

1
我发现一个URL谈论未记录的-E(但它似乎是一个死链接;感谢Google,它有Web存储版本)。 它相当于-r,与BSD兼容(请参见该死链接页面中的代码段: /* 未记录的,为了与BSD sed兼容。 */ case 'E': case 'r': if (extended_regexp_flags) usage(4); extended_regexp_flags = REG_EXTENDED; break; . . . - Scott Chu
那个链接有时候可以用,所以我会在这里发布它的URL:http://blog.dmitryleskov.com/small-hacks/mysterious-gnu-sed-option-e/。 - Scott Chu
从手册(man sed)中:-E,-r,--regexp-extended;在脚本中使用扩展正则表达式(为了可移植性,请使用POSIX -E)。另请参阅https://www.gnu.org/software/sed/manual/html_node/Extended-regexps.html。 - Wilf

1
cat <<-EOF > file1.txt
1aaa
2eee

Test        XXX
Hanna
Lars
EOF

cat file1.txt | sed -e '/Test *XXX/p' -e '0,/Test *XXX/d'

输出:

Test        XXX
Hanna
Lars

解释:

  • -e '/Test *XXX/p' 复制匹配 /Test *XXX/ 的行
  • -e '0,/Test *XXX/d' 删除从第0行到第一个匹配/Test *XXX/的行

通过复制行,然后删除第一行,我们有效地保留了匹配的行,成功地删除了Test XXX之前的所有行。

注意:如果有多个Test XXX行,则此方法不能按预期工作。


1

你可以使用 bash 来完成它(例如对于一个文件)

t=0
while read -r line
do
    [[ $line =~ Test.*XXX ]] && t="1"
    case "$t" in
     1) echo "$line";;
    esac
done < file > tempo && mv tempo file

使用for循环必要时遍历所有文件


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接