【问题标题】:Shell script to fetch a value from a file and save it to other用于从文件中获取值并将其保存到其他文件的 Shell 脚本
【发布时间】:2019-10-18 01:27:19
【问题描述】:

我在一个文件中有一些文本,我想使用 shell 脚本将这些文本复制到另一个文件中。

这是脚本-

#!/bin/sh

PROPERTY_FILE=/path/keyValuePairs.properties

function getValue {
   FIELD_KEY=$1
   FIELD_VALUE=`cat $PROPERTY_FILE | grep "$FIELD_KEY" | cut --complement -d'=' -f1`
}

SERVER_FILE=/path/FileToReplace.yaml

getValue "xyz.abc"
sed -i -e "s|PASSWORD|$FIELD_VALUE|g" $SERVER_FILE

keyValuePairs.properties:

xyz.abc=abs

FileToReplace.yaml:

someField:
    address: "someValue"
    password: PASSWORD

脚本的目标是从 keyValuePairs.properties 中获取“abs”,并将其替换为 FileToReplace.yaml 中的 PASSWORD 字段。 FileToReplace.yaml 应该看起来像

someField:
    address: "someValue"
    password: abs

注意 - 文本中可能有“=”而不是“abs”。它也应该可以正常工作。

目前的情况是,当我运行脚本时,它会将 FileToReplace.yaml 更新为

someField:
    address: "someValue"
    password: 

将值设置为空。

谁能帮我弄清楚这个脚本有什么问题?

注意 - 每当我执行脚本时,我都会遇到问题 -

sh scriptToRun.sh 
cut: illegal option -- -
usage: cut -b list [-n] [file ...]
       cut -c list [file ...]
       cut -f list [-s] [-d delim] [file ...]

如果我使用 gcut,代码可以正常工作,但我不能使用 gcut(需求问题)。我需要使用 cut 来解决这个问题。

【问题讨论】:

  • 应该$PROP_KEY$FIELD_KEY
  • 没错。谢谢指出!
  • 但是,同样的问题仍然存在。我编辑了这篇文章的文字。
  • 尝试将 cut 更改为 cut -d'=' -f2 或在 bash 而不是 sh 中运行,除非这是必需的
  • cat $PROPERTY_FILE | grep "$FIELD_KEY"这行可以直接改写为grep "$FIELD_KEY" $PROPERTY_FILE,避免Useless use of cat

标签: bash shell sh cut


【解决方案1】:

您的脚本存在一些问题:

  1. FIELD_VALUEgetValue() 函数的本地函数。
  2. getValue() 将匹配行中任意位置包含 FIELD_KEY 的行(例如 some.property=string.containing.xyz.abc
  3. getValue() 可以返回多行。
  4. 将更新服务器文件中出现的所有字符串“PASSWORD”,而不仅仅是“password: PASSWORD”行中的字符串。

如果您可以使用bash 而不是sh,这应该可以解决所有问题:

#!/bin/bash

declare    property_file=/path/keyValuePairs.properties
declare    server_file=/path/FileToReplace.yaml
declare    property="xyz.abc"

property_line=$(grep -m 1 "^${property}=" ${property_file}" )

sed -i 's|^\(\s*password:\s*\)PASSWORD\s$|\1'${property_line##*=}'|g' ${server_file}

【讨论】:

  • 我的脚本仍然有一些问题:1) 它没有检查它是否正在更新文件正确部分的密码字段。如果有多个部分包含密码字段,它们都将被更新。 2) 如果属性文件中的相应行包含空格,则脚本将找不到该属性。如果这些问题很重要,请告诉我。它们可以用更多的代码来修复。
【解决方案2】:

我发布的原始代码有效。我在 shell 中使用了错误的文件名(在我的真实代码中),这导致它无法读取值,因此将其设置为空。

【讨论】:

    【解决方案3】:

    将剪切命令替换为:

    cut -d'=' -f2-

    它应该适用于所有版本的cut。

    -f2- 表示字段 2 及以后的所有字段。这是处理包含“=”的值所必需的。

    是的,某些字符会导致 sed 命令出现问题。如果不在这里遇到麻烦,很难获得一个强大的解决方案。 python 脚本可能是更好的选择。

    如果 shell 脚本是唯一的选择,你可以试试这样:

    (sed -n -e '1,/PASSWORD/p' FileToReplace.yaml | head -n -1;
    echo "    password: ${FIELD_VALUE}";
    sed -n -e '/PASSWORD/,$ p' FileToReplace.yaml) > FileToReplace.yaml.new \
    && mv FileToReplace.yaml.new FileToReplace.yaml
    

    但它变得相当丑陋。 (将文件打印到包含“PASSWORD”的行,然后回显完整的密码行,然后打印文件的其余部分)

    你也可以这样使用:

    cat << EOF > FileToCreate.yaml
    someField:
        address: "someValue"
        password: ${FIELD_VALUE}
    

    如果保留文件的旧内容并不重要。

    【讨论】:

    • 这很好用!但是如果我只是在 keyValuePairs.properties (xyz.abc=&) 中使用“&”,那么它不会替换 FileToReplace.yaml 中的值。有什么办法可以做到这一点?
    • “-f2”和“-f2-”到底有什么区别?
    • 就像 & 一样,脚本无法处理这些字符 / : "
    猜你喜欢
    • 2021-12-24
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    相关资源
    最近更新 更多