【问题标题】:Read a file and edit the file at the same time (line by line) in bash在bash中读取文件并同时(逐行)编辑文件
【发布时间】:2019-09-02 07:58:29
【问题描述】:

假设我有一个文件temp.yaml

# Comment shouldn't be deleted
passwords:
    key1: __password__
    key2: __password__
    key3: __password2__
    key4: __password__
# All comments should be preserved
passwords-new:
    key1: __newPassword__

在这个文件中,我想让每个 __password__ 字段具有不同的值。本质上,此文件中的所有密码都有不同的值。

我正在考虑逐行读取文件并使用新生成的密码存储/替换密码。但不确定,如何逐行浏览文件并在 bash 中同时编辑该特定行。

任何其他解决方案或更好的方法也可以。

【问题讨论】:

  • 请展示您的尝试并解释为什么不满意。
  • 一般的想法是你不要这样“编辑”行。您从一个文件中读取一行并写入另一个文件。
  • 目前,我已经分别使用 sed 搜索“key1: password”并将其替换为“key1: xysdxy”。但是将来,如果我们想添加一个新密钥,我们希望自动处理它,并且不希望有人为新密钥编辑新的 sed 语句。
  • 您是否有理由要使用 bash 而不是这样的:stackoverflow.com/questions/7255885/…
  • 几乎我们的整个代码库都在该产品的 bash 中。所以我们正在寻找在 bash 中最简单、最简单的方法。

标签: bash shell sh


【解决方案1】:

如果 YAML 文件不是太大,您可以使用 Bash 代码在内存中进行编辑并将结果写回文件。这个Shellcheck-clean 代码演示了这个想法:

#! /bin/bash -p

# Set passwords in a YAML file.  Update the file in place.
function set_yaml_passwords
{
    local -r yaml_file=$1

    # Create a regular expression to match key/password lines
    local -r key_rx='^([[:space:]]*key[[:digit:]]*:[[:space:]]*)'
    local -r pw_rx='__[[:alnum:]]*[Pp]assword[[:alnum:]]*__[[:space:]]*$'
    local -r key_pw_rx=${key_rx}${pw_rx}

    # Read the YAML file lines into an array, setting passwords as we go
    local yaml_lines=() is_updated=0
    local line keystring newpw
    while IFS= read -r line || [[ -n $line ]] ; do
        if [[ $line =~ $key_pw_rx ]] ; then
            keystring=${BASH_REMATCH[1]}
            newpw=$(pwgen 10)
            yaml_lines+=( "${keystring}${newpw}" )
            is_updated=1
        else
            yaml_lines+=( "$line" )
        fi
    done <"$yaml_file"

    # If any passwords have been set, update the YAML file
    if (( is_updated )) ; then
        printf '%s\n' "${yaml_lines[@]}" >"$yaml_file"
        printf "Updated '%s'\\n" "$yaml_file" >&2
    fi

    return 0
}

set_yaml_passwords 'temp.yaml'

这是通过在问题中给出的示例 YAML 文件上运行上述代码生成的 YAML 文件示例:

# Comment shouldn't be deleted
passwords:
    key1: yai9cegiD4
    key2: Ahtah1eyoh
    key3: ya1teo1ooB
    key4: AhGae5EiLe
# All comments should be preserved
passwords-new:
    key1: oaKoh0teiK
  • Bash 代码中的逐行处理非常慢。上面的代码在我的(旧版)Linux 系统上处理一个一万行文件(带有少量密钥/密码行)花了将近 1 秒。在现代系统上,您会在遇到内存问题之前很久就遇到时间问题。
  • 我使用pwgen 10 生成新密码。你可能想做点别的。
  • 演示代码中没有错误检查。真正的代码应该检查丢失的文件、不可读的文件、不可写的文件、函数的参数数量错误等。

【讨论】:

    猜你喜欢
    • 2019-12-31
    • 1970-01-01
    • 1970-01-01
    • 2013-02-16
    • 1970-01-01
    • 1970-01-01
    • 2021-02-14
    • 1970-01-01
    相关资源
    最近更新 更多