shell sed根据字符串匹配删除除最后一行以外的所有行

zhte4eai  于 2023-05-07  发布在  Shell
关注(0)|答案(5)|浏览(301)

从一个特定的用户那里得到了旧密钥autorized_keys,比如alice,并希望保留最后修改的公钥并删除其余的公钥。
下面是autorized_keys文件的示例内容:

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA0YnNYVo/lHtSLtDUpQIqgS8WIpoBA7NRfaheQZXjqOjDMmBZA0cJy+ng3kmUuh5SbNapjaAYFwMHjLv6biHAasWgE77rJYXN8+JpHi/JwuXUnVUTwHrKXvkMr0sPgDxCEZO15GtiJwVPfmxpl3RBB/we5a+A6fhvXCyk/dxQRdU= alice-publickey
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDp6d0GmH5Q+lbx832n2W43Ikx8cpTeM8MRQ1yJmnhzaCSkQk9jWkwB5Msvj7uR923k0qLCZQ4ZbdPQ7liK9+Ks/7c0yDrBkU1KVOBNDQD1ck9Iwo2qwsS72b1kf4zeNKVJWkKBcFg7qxOmjIy9wNJ0XhbHmo/9gkp/hoOY3g0I5tExIlVdTH+uhEmOerghChTHTWU/kymZW0yYbDKl9zyPEDY9Hf/0Mt6g2dz+q3/cfcwCIZIeR5/Fjt7xXbt+fqmaiws1veGacw60u8ouMJ4DL9CcXRUbZHdEY4v2yIcEZRXMv9Q/6s0TcuC9s6Z5n2RzV8eW3RCZuzMWmYlkcA/H bob-publickey
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAsB3XsrmTHWygTrL8dT/Z5+qjjXfPxH7IPlyFZt0QcHA1a16g0ZPeEMB1RUu90vtbEvKjq+hAAANeLcmVW85i8LSsO3xcuCGTFNVNx2up7Fv7YxiHMJpfQqyiBW09HixrPiu+9Wl/olTB9kPu+fZ/jRqok3ZTARnQDoE2g1RWnNU= alice@mcosmac
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2UFK8Y7mODUZ7a2glErZbKk9hUy1pCOiGz4arAlTBiJ884vrjGaYNGFyWiNvqNKxLWn6Cul1eyPF1M/Z6l6QE3biJgJPln2ZZIoMcsNiCrFl0x5tUdnyVnVGz5pZTI1/0IFFLE4jbW2grMHOC7z+ik3WOD5aTj8pUWeTIeppMKLwjnJhm0ALsmLZqhtwnhgLSg9m4NQmcLWt5s0P/Z91hUKw2tY5iV9yOu5tS+oTMoeV7ays9MXM9ozpehLhsbqn98O7k2UpQzoWEo093lAjzydnBICd5tKdVJyGcyi3BLY4xhU+dnJ9NIUuYtnLZEhAGCbOQEGNivkxDQv1ccRTx trudy@newMacs
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPbEzZDSZNKdGsH0sP10abmosX0yFquCEx2ibNzmh0AvvsR6pbA/pdl1i9XqIJlDBustWfmnChXEQz9Nft5LbM/moR6DAe7Wd70kmY8CreGgZ2kF8KCZ3bTkKYfO5PexKRCZ8IFRs6xswbfV0DJOmGnNo+wKOFDK/J7GVd9e1u6FebSo/Nr0QN/maXKN+Tc57GnV+j34ihD9PoRmfGYRIjm/vMkfUB9l1fZDEawdMO+Ats+G9gSvlhIm4TSP4sHk+zUJJff+j6ubMsGW0Flh4YjVJMMSU9vrpsTS5WiEbsZVxuWkrd+9jMo5RGDoWt2HADo4Dup0DlyM1pj2u1zbfl alice@brandNew

下面的选项看起来可以帮助我使用sed进行过滤&正如我们所知,使用-i选项,我们可以直接进行文件内编辑。但我不确定在机器上为用户alice注册的旧密钥的数量。

grep alice authorized_keys | sed '1,2d'
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPbEzZDSZNKdGsH0sP10abmosX0yFquCEx2ibNzmh0AvvsR6pbA/pdl1i9XqIJlDBustWfmnChXEQz9Nft5LbM/moR6DAe7Wd70kmY8CreGgZ2kF8KCZ3bTkKYfO5PexKRCZ8IFRs6xswbfV0DJOmGnNo+wKOFDK/J7GVd9e1u6FebSo/Nr0QN/maXKN+Tc57GnV+j34ihD9PoRmfGYRIjm/vMkfUB9l1fZDEawdMO+Ats+G9gSvlhIm4TSP4sHk+zUJJff+j6ubMsGW0Flh4YjVJMMSU9vrpsTS5WiEbsZVxuWkrd+9jMo5RGDoWt2HADo4Dup0DlyM1pj2u1zbfl alice@brandNew

有没有办法删除alice的所有旧键,除了最后一个保存alice的字符串匹配的键?

z9smfwbn

z9smfwbn1#

sed并没有真正有一个很好的“最后一个匹配行”的概念;但这对于Awk来说相对容易。

awk '{ l[++n] = $0 }
  /alice/ { alice=NR }
  END { for(i=1; i<=n; i++) if (alice == i || !(l[i] ~ /alice/)) print l[i] }' file >file.new

这会将整个文件吸入内存,因此如果文件非常大,可能会寻找不同的解决方案。
开箱即用的Awk没有覆盖其输入文件的能力,尽管GNU Awk有一个-i inplace选项,其工作方式大致类似于sed -i

fjnneemd

fjnneemd2#

这可能对你有用(GNU sed):

sed -n '/alice/=' file | sed '$d;s/$/d/' | sed -f - -i file

查找Alice键的行号。
删除最后一个,并将所有其他转换为sed delete命令。
将上述命令应用于原始文件。

xqk2d5yq

xqk2d5yq3#

考虑一个awk解决方案:

awk 'NR==FNR {if (/alice/) last=FNR; next} !/alice/ || FNR == last' file file

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDp6d0GmH5Q+lbx832n2W43Ikx8cpTeM8MRQ1yJmnhzaCSkQk9jWkwB5Msvj7uR923k0qLCZQ4ZbdPQ7liK9+Ks/7c0yDrBkU1KVOBNDQD1ck9Iwo2qwsS72b1kf4zeNKVJWkKBcFg7qxOmjIy9wNJ0XhbHmo/9gkp/hoOY3g0I5tExIlVdTH+uhEmOerghChTHTWU/kymZW0yYbDKl9zyPEDY9Hf/0Mt6g2dz+q3/cfcwCIZIeR5/Fjt7xXbt+fqmaiws1veGacw60u8ouMJ4DL9CcXRUbZHdEY4v2yIcEZRXMv9Q/6s0TcuC9s6Z5n2RzV8eW3RCZuzMWmYlkcA/H bob-publickey
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2UFK8Y7mODUZ7a2glErZbKk9hUy1pCOiGz4arAlTBiJ884vrjGaYNGFyWiNvqNKxLWn6Cul1eyPF1M/Z6l6QE3biJgJPln2ZZIoMcsNiCrFl0x5tUdnyVnVGz5pZTI1/0IFFLE4jbW2grMHOC7z+ik3WOD5aTj8pUWeTIeppMKLwjnJhm0ALsmLZqhtwnhgLSg9m4NQmcLWt5s0P/Z91hUKw2tY5iV9yOu5tS+oTMoeV7ays9MXM9ozpehLhsbqn98O7k2UpQzoWEo093lAjzydnBICd5tKdVJyGcyi3BLY4xhU+dnJ9NIUuYtnLZEhAGCbOQEGNivkxDQv1ccRTx trudy@newMacs
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPbEzZDSZNKdGsH0sP10abmosX0yFquCEx2ibNzmh0AvvsR6pbA/pdl1i9XqIJlDBustWfmnChXEQz9Nft5LbM/moR6DAe7Wd70kmY8CreGgZ2kF8KCZ3bTkKYfO5PexKRCZ8IFRs6xswbfV0DJOmGnNo+wKOFDK/J7GVd9e1u6FebSo/Nr0QN/maXKN+Tc57GnV+j34ihD9PoRmfGYRIjm/vMkfUB9l1fZDEawdMO+Ats+G9gSvlhIm4TSP4sHk+zUJJff+j6ubMsGW0Flh4YjVJMMSU9vrpsTS5WiEbsZVxuWkrd+9jMo5RGDoWt2HADo4Dup0DlyM1pj2u1zbfl alice@brandNew

内联保存更改

对于gnu-awk

awk -i inplace 'NR==FNR {if (/alice/) last=FNR; next}
   !/alice/ || FNR == last' file file

对于posix awk

awk 'NR==FNR {if (/alice/) last=FNR; next}
   !/alice/ || FNR == last' file file > file.out && mv file.out file
j2datikz

j2datikz4#

这对ed来说比sed更重要,因为ed可以从文件的末尾开始查找匹配项:

ed -s keys.txt <<'EOF'
1;?alice?-1 g/alice/d
w
EOF

d删除从第一行到最后一个alice之前的范围内与alice匹配的每一行,然后w将文件写回磁盘。

czq61nw1

czq61nw15#

当文件中有另一个alice时,删除包含alice的行。
重复上述步骤,直到除最后一个外的所有爱丽丝都被移除。

sed -rz ':a;s/(\n|^)[^\n]*alice[^\n]*\n(.*alice)/\1\2/;ta' authorized_keys

相关问题