删除文件中匹配一个字符串但不匹配另一个字符串的行 - SED、BASH?
我想删除文件中包含“test”一词的所有行,但如果该行包含“test@”,那么我不想删除它。
可能有一些时髦的方法可以用 sed 来做到这一点,但我很挣扎,我尝试使用 sed 编写一个 bash 循环,但这可能很愚蠢。
filetest=/tmp/filetest
filetest_tmp=/tmp/filetest.tmp<
line_num=0
while read line; do
line_num=$(($line_num+1))
if [[ $line == *rootsh* ]] && [[ $line != *root@* ]]
then
sed -e "${line_num}"'d' $filetest >> $filetest_tmp
fi
done < $filetest
cp $syslog_tmp $filetest
正如你所知,我是这方面的新手:(
I want to remove all lines in a file which contain the word "test" but if that line contains "test@" then I do not want to delete it.
There is probably some funky way of doing this with sed but I am struggling, I tried to write a bash loop using sed but this is probably stupid.
filetest=/tmp/filetest
filetest_tmp=/tmp/filetest.tmp<
line_num=0
while read line; do
line_num=$(($line_num+1))
if [[ $line == *rootsh* ]] && [[ $line != *root@* ]]
then
sed -e "${line_num}"'d' $filetest >> $filetest_tmp
fi
done < $filetest
cp $syslog_tmp $filetest
As you can tell, I'm a newb at this :(
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
第一个模式匹配包含“test”的行;第二个模式删除行,除非它们匹配“test@”。
对数据文件进行测试:
输出:
这似乎满足您的要求。
sed
脚本的该行中有两个正则表达式:/test/
— 查找包含test
的行。/test@/
— 查找包含test@
的行。/test/{…}
表示法的意思是“当该行与test
匹配时,在…
中执行该操作。/test@ /!d
表示“当该行与test@
不匹配时,将其删除”。macOS 上的
sed
需要分号(可能还有其他 BSD-)。基于 Unix 的版本);对于 GNU 可以省略它sed
,但由于它适用于两者(并且我最常在 macOS 上进行测试),因此保留它似乎是明智的做法,它标志着!d
命令的结束。The first pattern matches the lines containing 'test'; the second pattern deletes lines unless they match 'test@'.
Tested on the data file:
Output:
That seems to meet your requirements.
There are two regular expressions in that line of
sed
script:/test/
— looks for lines containingtest
./test@/
— looks for lines containingtest@
.The
/test/{…}
notation means "when the line matchestest
, do that actions in…
.The
/test@/!d
means "when the line does not matchtest@
, delete it".The semicolon is needed with
sed
on macOS (and probably other BSD-based versions of Unix); it could be omitted with GNUsed
, but since it works with both (and I test on macOS most often), it seems sensible to keep it. It marks the end of the!d
command.使用
grep
:通常
grep
打印匹配的行,但-v
告诉它打印不匹配的行。正则表达式匹配任何出现的“test”,后跟除“@”之外的任何内容。如果您不必期望在行尾出现“test”,那么这很好。如果是这种情况,请使用
我认为不值得深入研究为什么您的解决方案不起作用,因为它在很多方面都被破坏了。
Use
grep
:Usually
grep
prints matching lines but-v
tells it to print non-matching lines.The regular expression matches any occurance of "test" that is followed by anything but a '@'. This is fine if you don't have to expect "test" coming up at the end of a line. If that is the case, use
I don't think it is worth going into why your solution does not work, because it is broken in so many ways.
如果您稍微翻转一下问题,它就会变成:
如何从文件中过滤出包含字符串“test@”或不包含字符串“test”的所有行。
例如,这可以在 awk 中完成,如下所示:
乔纳森的答案也有效,我只是想给你一个替代版本。
If you flip your question around a bit, it becomes:
How do I filter out all lines from a file that either contains the string 'test@' or does not contain the string 'test'.
This can for example be done in awk like this:
Jonathan's answer also works, I just wanted to give you an alternate version.
如果您使用
ed
,则不需要 tmp 文件!There is no need for a tmp file if you use
ed
!