我想将 NoDisplay=true 附加到 .desktop 文件,但前提是该条目不存在。我按以下方式执行此操作:
grep -q 'NoDisplay=true' '/usr/share/applications/yelp.desktop' || bash -c 'echo "NoDisplay=true" >> /usr/share/applications/yelp.desktop'
我想知道是否有更短的单线可以进行相同的操作?
我在 bash 脚本中使用此命令,并且必须使用命令“bash -c”。
答案1
如果你有 GNU sed
,那就相当简单了:
sed -zi '/NoDisplay=true/!s/$/\nNoDisplay=true/' file
选项-z
在模式空间中一次处理整行(不建议用于大文件)。如果未找到 ( ) 设置!
,则将其附加到末尾并嵌入换行符。注意:替换字符串中的-i
、-z
和\n
不是标准的,因此不可移植。
答案2
这个有点短。
grep -q 'NoDisplay=true' '/usr/share/applications/yelp.desktop' || echo "NoDisplay=true" >> /usr/share/applications/yelp.desktop
还有一个专门为此 Augeas 设计的工具 ( augtool
)。我还没有将它与.desktop
文件一起使用。所以无法帮助您了解如何使用它。
答案3
使用sed
, 基于这个答案:
sed -i "/^NoDisplay=true\$/h;\${x;/^\$/{s//NoDisplay=true/;H};x}" '/usr/share/applications/yelp.desktop'
没有转义 s 就分解$
:
# Store the line in the hold space if found
/^NoDisplay=true$/h
# At the end of the file
${
# Switch to the hold space
x
# If it's empty
/^$/{
# Replace the line
s//NoDisplay=true/
# Store it in the hold space
H
}
# Switch to the hold space
x
}
这是可以做的awk
,但因为没有就地编辑在 GNU 4.1.0 之前,您基本上会做与grep
+相同的事情echo
。
答案4
我认为你的方法中唯一可能不优雅的事情是使用 a bash -c
,这不是必需的,以及用于模式和文件名的文字字符串的冗余,这实际上使你的单行很长,并且您可以将其放入要使用的变量(可能是短名称)中,例如:
p='NoDisplay=true' f='/usr/share/applications/yelp.desktop'; grep -q "${p}" "${f}" || echo "${p}" >>"${f}"
您可以通过使用重定向来使其更加紧凑,只是为了避免指定文件名两次,从而避免使用一个变量,如下所示:
p='NoDisplay=true'; (grep -q "${p}" || echo "${p}" >&0) <>/usr/share/applications/yelp.desktop
但这是否真的优雅可能是一个偏好问题。
无论如何,尽管通过变量,但模式仍然需要指定两次。我无法想象有什么方法可以避免这种情况。
另一个使用 的变体sed
可能是:
p='NoDisplay=true'; sed -n "/${p}/q;\$a${p}" <>/usr/share/applications/yelp.desktop >&0
需要 GNU sed
(通常出现在 Linux 上),因为a
命令后面紧跟着要附加的文本(在我们的例子中是模式的变量)。
对于 POSIX 来说sed
也是如此:
p='NoDisplay=true'; sed -n "/${p}/q;\$a\\
${p}
" <>/usr/share/applications/yelp.desktop >&0