sed 替换文件中的字符

eek*_*nky 3 command-line sed text-processing

我需要替换 a 中的单个字符/etc/request-key.conf

文件格式为;

###############################################################################
#
# Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
# Written by David Howells (dhowells@redhat.com)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version
# 2 of the License, or (at your option) any later version.
#
###############################################################################


###############################################################################
#
# We can run programs or scripts
# - Macro substitutions in arguments:
#   %%...   %...
#   %o  operation name
#   %k  ID of key being operated upon
#   %t  type of key being operated upon
#   %d  description of key being operated upon
#   %c  callout info
#   %u  UID of requestor
#   %g  GID of requestor
#   %T  thread keyring of requestor (may be 0)
#   %P  process keyring of requestor (may be 0)
#   %S  session keyring of requestor (may be the user's default session)
#
################################################################################

#OP TYPE    DESCRIPTION CALLOUT INFO    PROGRAM ARG1 ARG2 ARG3 ...
#====== ======= =============== =============== ===============================
create  dns_resolver *      *               /sbin/key.dns_resolver %k
create  user    debug:*     negate      /bin/keyctl negate %k 30 %S
create  user    debug:*         rejected        /bin/keyctl reject %k 30 %c %S
create  user    debug:*         expired         /bin/keyctl reject %k 30 %c %S
create  user    debug:*         revoked         /bin/keyctl reject %k 30 %c %S
create  user    debug:loop:*    *       |/bin/cat
create  user    debug:*     *       /usr/share/keyutils/request-key-debug.sh %k %d %c %S
create  cifs.spnego *   *       /usr/sbin/cifs.upcall -c %k
create  dns_resolver    *   *       /usr/sbin/cifs.upcall %k
negate  *   *       *       /bin/keyctl negate %k 30 %S
Run Code Online (Sandbox Code Playgroud)

所以我需要从最后一行开始;

create cifs.spnego * * /usr/sbin/cifs.upcall -c %k

到;

create cifs.spnego * * /usr/sbin/cifs.upcall -t %k

我试过了;

sed -i 's/^\(create cifs.spnego *cifs.upcall\) \(%k\)/\1 -t \2/' /etc/request-key.conf

卜treally我只需要更换-c一个-t

ter*_*don 8

正则表达式的黄金法则是:少即是多。始终尝试找到足以定位搜索字符串的最简单的表达式。因此,与其尝试匹配整行,不如寻找一个小而独特的字符串:

$ grep -- -c file
create  cifs.spnego *   *       /usr/sbin/cifs.upcall -c %k
Run Code Online (Sandbox Code Playgroud)

我将您的文件另存为file,如您所见,-c文件中只有一种情况。所以你需要的是(注意-i.bak,这将创建一个备份文件):

sed -i.bak 's/-c/-t/' /etc/request-key.conf
Run Code Online (Sandbox Code Playgroud)

如果您想更加谨慎并确保只匹配目标行而不先搜索,只需更改-ccreate cifs.spnego. 请注意使用-Efor 扩展正则表达式并使用\s+(1 个或多个空格)而不是尝试写入多个空格:

sed -Ei.bak 's/^(create\s+cifs\.spnego.*cifs.upcall\s+)-c/\1 -t/' /etc/request-key.conf
Run Code Online (Sandbox Code Playgroud)

由于您不需要在 之后进行任何更改-c,因此没有理由尝试匹配它:less is more


您尝试失败的原因是因为*是正则表达式中的乘数,它的意思是“0 或更多”。所以,当你有cifs.spnego *cifs.upcall,这看起来对cifs.spnego,那么0或多个空格,后面cifs.upcall。然而,你的台词是:

create  cifs.spnego *   *       /usr/sbin/cifs.upcall  -t %k
Run Code Online (Sandbox Code Playgroud)

要匹配它,您需要匹配cifs.spnego,然后是一个空格,然后是一个*,然后是更多的空格,然后是另一个*,然后/usr/sbin/只有这样您才能拥有cifs.upcall. 要匹配所有这些,您需要(您需要\*匹配字符*):

/^create  cifs.spnego \*   \*       cifs.upcall/
Run Code Online (Sandbox Code Playgroud)

或者,因为少即是多,简单地说:

/^create  cifs.spnego .*cifs.upcall/
Run Code Online (Sandbox Code Playgroud)

.*意思是“什么”。