【问题标题】:sed with variable as argument in bash scriptsed 变量作为 bash 脚本中的参数
【发布时间】:2015-06-03 14:31:05
【问题描述】:

我正在尝试编写一个 bash 脚本来扫描 authorized_keys 文件,并在找到时删除几个以前员工的密钥。我花了很长时间弄清楚最后 sed 命令的转义。我使用逗号而不是 / 因为 / 可以显示在 ssh-key 中。任何帮助将不胜感激

#!/bin/bash

declare -A keys
keys["employee1"]='AAAAB3NzaC1yc2EAAAABJQAAAIEAxoZ7ZdpJkL98n8cSTkFBwaAeSNK0m/tOWtF1mu5NAzMM/+1SDO6rJH/ruyyqBJo9s+AHWZLGRHfXT2XBg2SRaUnubAKp0w6qNIbej0MsA/ifAs8AfVGdj0pUPLtKpo6XVZkB8vEZSIQ+xNk1n5HJrGJnFGWKWeY3z1/KOLxcLHU='
keys["employee2"]='AAAAB3NzaC1yc2EAAAABIwAAAQEAwHYNAVhb319OBVXPhYF8cSTkFBwaAekr7UcKjfLPCHMpz19W0L/C0g+75Hn8COxOQILDUhIPhYHXOduQjGD/6NXgJDWxgyT00Azg5BREUnBd58WqZPlEvTZYlAgmdMIbnWPPGdJwzqKH/k7/STK6vTKxL6rxBo4lSNK0m/tOWtF1mu5NAzMM/+1SDO6rJH/ruyyqBJo9s+NIbej0MsA/ifAs8AfAkfO2JjgeQpJMyZ7B02XVN5iSLAyC3Cb5FXIjJuk4LPhcApuVyszH2lgve0r5bt/nFgVujJTvJTHPlGrqkYDcDJVUtfbjoLqGPrnpijp6rGIC7aFDDe7bk0ygHYMXDFWcjJBerfLGUWTYWFFLY3bfiO/h/9oEycmQHyB2co4a0IyyDnaYn9OY6xsRRATVlk4Q=='

files=`find / -name authorized_keys`

echo "Checking Authorized_Keys files on: " `hostname`
echo ""
echo "Located files: "

for file in $files; do
  echo "  $file"
done

echo""

for file in $files; do
  for key in "${!keys[@]}"; do
    if grep -q ${keys[$key]} $file; then
      echo "  *** Removing $key from $file"
      sed "s,${keys[$key]},d" $file
    fi
  done
done

【问题讨论】:

    标签: linux bash sed


    【解决方案1】:

    我想你把它弄得有点复杂。

    您可以使用grep -vf进程替换来做到这一点:

    # array to hold the value you want to remove
    keys=(
    'AAAAB3NzaC1yc2EAAAABJQAAAIEAxoZ7ZdpJkL98n8cSTkFBwaAeSNK0m/tOWtF1mu5NAzMM/+1SDO6rJH/ruyyqBJo9s+AHWZLGRHfXT2XBg2SRaUnubAKp0w6qNIbej0MsA/ifAs8AfVGdj0pUPLtKpo6XVZkB8vEZSIQ+xNk1n5HJrGJnFGWKWeY3z1/KOLxcLHU=',
    'AAAAB3NzaC1yc2EAAAABIwAAAQEAwHYNAVhb319OBVXPhYF8cSTkFBwaAekr7UcKjfLPCHMpz19W0L/C0g+75Hn8COxOQILDUhIPhYHXOduQjGD/6NXgJDWxgyT00Azg5BREUnBd58WqZPlEvTZYlAgmdMIbnWPPGdJwzqKH/k7/STK6vTKxL6rxBo4lSNK0m/tOWtF1mu5NAzMM/+1SDO6rJH/ruyyqBJo9s+NIbej0MsA/ifAs8AfAkfO2JjgeQpJMyZ7B02XVN5iSLAyC3Cb5FXIjJuk4LPhcApuVyszH2lgve0r5bt/nFgVujJTvJTHPlGrqkYDcDJVUtfbjoLqGPrnpijp6rGIC7aFDDe7bk0ygHYMXDFWcjJBerfLGUWTYWFFLY3bfiO/h/9oEycmQHyB2co4a0IyyDnaYn9OY6xsRRATVlk4Q=='
    )
    
    while IFS= read -d '' -r file; do
        grep -vf <(printf "%s\n" "${keys[@]}") "$file" > "$file.tmp"
        mv "$file.tmp" "$file"
    done < <(find / -name authorized_keys -print0)
    

    【讨论】:

    • 我收到以下错误。 ./remove.sh:第 9 行:意外标记附近的语法错误 &lt;(find / -name authorized_keys -print0)' ./remove.sh: line 9: done
    • 请注意:直接将 find 命令的输出通过管道传输到 while 循环中也可以。
    • 是的,这会起作用,但它会派生一个不必要的子shell。
    【解决方案2】:

    在你的情况下,这很简单,只需要使用base64代码中不包含的符号作为分隔符,例如|

    sed "\|${keys[$key]}|d" $file
    

    sed中的解释manual

    \%正则表达式%

    (% 可以替换为任何其他单个字符。)

    这也匹配正则表达式 regexp,但允许使用与 / 不同的分隔符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-29
      • 2010-11-13
      • 1970-01-01
      • 2016-08-10
      • 2010-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多