shell 仅当行不包含关键字时追加到匹配行

qq24tv8q  于 2023-10-23  发布在  Shell
关注(0)|答案(5)|浏览(148)

我有一个文件,让我们称之为input.txt。它有很多行,但唯一相关的一行包含一个模型语句;
height ~ mu gender
它还可以包含;
height !n ~ mu date_birth !r g
因此,在正则表达式中标识行的一致性因子将是^height.*~.*$。至少到目前为止,这是我设计的。
我想追加!r g到结束行只有当!r g还没有出现。我试着把hereherehere的答案混合在一起,但我找不到。我更喜欢一个命令。也一直在玩复杂的awksed的,但我觉得这是过于简单,它不需要太难的人与经验。

预期结果:

如果height ~ mu gender,则height ~ mu gender !r g
如果height !bin ~ mu date_birth !r g,那么什么都不需要发生。
如果height !bin ~ mu gender,则height !bin ~ mu gender !r g

编辑:

到目前为止,我试过了;
如果!g存在,则sed '/^height.*~.*!r.*$/ ! s/$/!r g/' input.txt正确跳过行,但将其附加到input.txt中的每一行。
sed '/^height.*$/s/$/!r g/' input.txt,仅正确地附加到匹配行,而且如果!r g已经存在。

cwxwcias

cwxwcias1#

我们可以用sed来做这件事。首先,我们选择开始为height且包含~的行。对于这些行,如果行的结尾不是!r g,我们可以用!r g替换行的结尾:

#/usr/bin/sed -f

/^height .*~/{
/ !r g$/!s/$/ !r g/
# Explanation:
# / !r g/           : select lines marked with the tag
#       !s          : in lines that don't match, substitute
#          $        : end of line
#             !r g  : the tag to add
}

演示

$ ./45876917.sed <<END
height ~ mu gender
height !bin ~ mu date_birth !r g
height !bin ~ mu gender
END
height ~ mu gender !r g
height !bin ~ mu date_birth !r g
height !bin ~ mu gender !r g
nvbavucw

nvbavucw2#

另一个在awk:

$ awk '{sub(/( !r g)?\r?$/," !r g")}1' file
y ~ a b c !r g
y !n ~ d e f !r g
y !n ~ d e f !r g

或者使用更改的数据:

height ~ mu gender !r g
height !bin ~ mu date_birth !r g
height !bin ~ mu gender !r g

注意正则表达式中的\r?,它是Windows行的第一部分,以\r\n结尾。如果它存在,它将被替换。

sauutmhj

sauutmhj3#

sed '/^y.*~.*$/{/!r g/!{s/.*/& !r g/}}' input.txt

例如

$ cat input.txt
y !n ~ d e f !r g
y ~ a b c

$ sed '/^y.*~.*$/{/!r g/!{s/.*/& !r g/}}' input.txt
y !n ~ d e f !r g
y ~ a b c!r g

更新

上面的sed命令将考虑所有具有模式^y.*~.*$的行,并且仅当该行的任何部分都不包含!r g时才将!r g附加到行的末尾。
要更改过滤的行,只需将开始的正则表达式^y.*~.*$更新为您需要的。

rdlzhqv9

rdlzhqv94#

  • awk* 解决方案:
awk '/^y.*~.+/ && !/!r g/{ $0=$0" !r g" }1' input.txt
inkz8wg9

inkz8wg95#

我们如何在行的末尾附加关键字“world”,以防它从那里丢失:

echo "hello world
hello
hello world" | awk '{ print $0, ($NF=="world")? "" : "world"; }'

# # Output:
# Hello world
# Hello world
# Hello world

一个实际的例子:在行尾添加关键字“[not installed]”,以防此处缺少相反的关键字(“[installed*”):

# By default 'apt list' will only print '[installed]' or '[installed,automatic]' at the end of the installed packages 
# and nothing at the end of non-installed packages. Creating more verbosity by piping to awk
apt -qq list pv gawk gnome-disk-utility | awk '{ print $0, ( match( $NF , "\\[installed" ) ) ? "" : "[not installed]"; }'

# Output:
# gawk/jammy-updates,jammy-security,now 1:5.1.0-1ubuntu0.1 amd64 [installed,automatic] 
# gawk/jammy-updates,jammy-security 1:5.1.0-1ubuntu0.1 i386 [not installed]
# gnome-disk-utility/jammy,now 42.0-1ubuntu1 amd64 [installed] 
# pv/jammy 1.6.6-1build2 amd64 [not installed]

相关问题