Bash 在shell中搜索字符串,如果未找到,则打印新行

Bash 在shell中搜索字符串,如果未找到,则打印新行,bash,shell,Bash,Shell,我有命令输出: Test TXT some Text1 Test TXT some Text2 Done TXT some Text3 Done TRT some Text1 Test TXT copy Text5 Done TXT some Text2 Test TRT many Text4 Test TRT some Text6 Done TXT many Text9 我想搜索TXT,如果找到,打印该行的其余部分。如果找不到,请打印一个空白行,如下所示: some Text1 some T

我有命令输出:

Test TXT some Text1
Test TXT some Text2
Done TXT some Text3
Done TRT some Text1
Test TXT copy Text5
Done TXT some Text2
Test TRT many Text4
Test TRT some Text6
Done TXT many Text9
我想搜索TXT,如果找到,打印该行的其余部分。如果找不到,请打印一个空白行,如下所示:

some Text1
some Text2
some Text3

copy Text5
some Text2


many Text9
如何在不使用sed或awk的情况下执行此操作?

这应该可以做到

if [[ "$line" == *TXT* ]]; then
    echo "$line"
else
    echo ""
fi
甚至更短:

[[ "$line" == *TXT* ]] && echo "$line" || echo ""
编辑:是的,就这样

$ while read line; do [[ "$line" == *TXT* ]] && echo "$line" || echo "" ; done <test.txt
Test TXT some Text1
Test TXT some Text2
Done TXT some Text3

Test TXT copy Text5
Done TXT some Text2


Done TXT many Text9

在你的问题中,你写了如何在不使用sed的情况下实现这一点,但在@Cyrus you write的回答下面,我不能使用awk,我们可以只使用sed吗

如果这是您想要的sed解决方案,您只需使用:

sed '/TXT/!s/^.*$//' file | sed '/TXT/s/^.*TXT[ ]//'
示例使用/输出

将您的文件用作文件,您将获得以下信息:

$ sed '/TXT/!s/^.*$//' file | sed '/TXT/s/^.*TXT[ ]//'
some Text1
some Text2
some Text3

copy Text5
some Text2


many Text9
解释

sed'/TXT/!s/^.*$/'文件查找所有行,例如不包含TXT并简单地使其为空; 通过管道连接到sed'/TXT/s/^.*TXT[]/',然后查找包含TXT的所有行,并从行首到TXT进行修剪,消除TXT后面的空格。
仔细检查一下,如果您还有其他问题,请告诉我。

这里有一个使用perl和非贪婪正则表达式的示例。*?代替sed或awk:

$ perl -pe 's/.*?(TXT |$)//' file
some Text1
some Text2
some Text3

copy Text5
some Text2


many Text9

它将非贪婪地删除并替换为空,直到TXT或$行的末尾。

这是一个绝对糟糕的答案。我很惊讶它能起作用。我把它贴在这里,希望有人能告诉我它为什么有效。我不理解的部分是为什么空白行出现-毕竟,没有“txt”分隔符的行不匹配任何模式,不应该提供输出,所以我想:

awk -F'TXT ' '{print $2}'
下面是测试:

awk -F'TXT' '{print $2}' <<EOF
> Test TXT some Text1
> Test TXT some Text2
> Done TXT some Text3
> Done TRT some Text1
> Test TXT copy Text5
> Done TXT some Text2
> Test TRT many Text4
> Test TRT some Text6
> Done TXT many Text9
> EOF
some Text1
some Text2
some Text3

copy Text5
some Text2


many Text9

请相信尤塔哈海德在这一点上的正确答案。UtahJarhead的回答只需要这个构造${line*TXT}就可以删除到'TXT'的最短的行前缀。

<公平的批评。你想要整行还是仅仅是一些文本1部分?你在这里写下如何不使用sed来实现这一点,但是在@Cyrus you write的回答下面我不能使用awk,我们可以只使用sed吗?。是哪一个?你想要sed还是其他什么?没有awkor sed,解决方案会变得更加棘手。你能提供更多的信息吗?比如:第二个字段总是3个字符吗?你能告诉我是哪一个吗?每行有3个空格,还是最后一个字段允许有更多的空格。
while 
  read line
do
[[ "$line" == *TXT* ]] && echo "${line#*TXT }" || echo ""
done