【问题标题】:How to save all variables from directory, in one file如何将目录中的所有变量保存在一个文件中
【发布时间】:2021-12-10 22:25:42
【问题描述】:

我想将目录中的所有变量保存在单独的文件中,删除重复项 首先,我将所有带有全局变量的行都写在一个单独的文件中

grep -rI "\$.*" folder/ >> output.txt

然后我试着把这个文件的变量拉出来

cat output.txt | sed /\$.*.[{A-Z}]/p

而且输出不是我所期望的

那么当 grep 之后的文件像这样时,我如何获取所需的变量:

something.text_text.txt:    - export IMAGE_NAME=${MY_REGISTY}/$MY_PR/${MY_PRNNN} something.text_text.txt:
- docker build --network host -t ${IMAGE_NAME}:${VERSION} -f $DILE_PATH --build-arg setupfile=$SET_FIL> something.text_text.txt: 
- docker push ${IMAGE_NAME}:${VERSION} something.text_text.txt:    - docker tag ${IMAGE_NAME}:${VERSION} ${IMAGE_NAME}:${MY_BUILD_REF_NAME} something.text_text.txt:    - docker push ${IMAGE_NAME}:${MY_BUILD_REF_NAME} something.text.txt:  
- /^rel_.*$/ something.text.txt:    - eval $(ssh-agent -s) something.text.txt:    - chmod 400 $MY_SSH_KEY something.text.txt:  
- ssh-add $MY_KEY something.text.txt:    - git checkout ${MY_BUIL_NAME} something.text.txt:    - git reset --hard origin/${MY_F_NAME} something.text.txt:    - mvn -s MY_settings.xml ${MTS} license:add-third-party something.text.txt:    - cat ${LICENSE_LIST_FILE} something.text.txt:      POM_XML_COMMIT_HASH_LOCAL=$(git log --oneline --follow -- pom.xml | awk '{ print $1 }' | head -n 1) || true something.text.txt:      echo POMIT_HASH_LOCAL=${PCOMMIT_HASH_LOCAL} something.text.txt:      POM_XML_COMMIT_HASH_REMOTE=$(git log --oneline origin/${MY_BUILD_REF_NAME} --follow -- pom.xml | awk '{ print $1 }' | h> something.text.txt:      echo POM_XML_COMMIT_HASH_REMOTE=${POM_OMMIT_HASH_REMOTE} something.text.txt:      if [[ ${POM_XML_COMMIT_HASH_LOCAL} = ${POMMIT_HASH_REMOTE} ]]; then something.text.txt:        echo "File pom.xml is the same for local and origin ${MY_BUILD_REF_NAME} branch." something.text.txt:        echo "New commits are presented in origin/${MY_BUILD_REF} branch for pom.xml file. Skipping." something.text.txt:    - git add -f ${LICENSE_LIST_FILE} something.text.txt:    - export MY_PUSH_URL=`echo $MY_REPOSITORY_URL | perl -pe 's#.*@(.+?(\:\d+)?)/#git@\1:#'` something.text.txt:    - git remote set-url --push origin "${MY_PUSH_URL}" something.text.txt:    - git push -f -o ci.skip origin ${MY_BUILD_REF_NAME} something.text_tests.txt:    - docker login -u $MY_REGISTRY_USER -p $MY_REGISTRY_PASSWORD $MY_REGISTRY something.text_tests.txt:    - export CONFIG_FILE=${HOME}/.docker/config.json something.text_tests.txt:   
- export VERSION=$(cat current_version) something.text_tests.txt:    - export MY_PROJECT_NAME_UPPER_CASE=$(echo ${MY_PROJECT_NAME} | tr a-z A-Z) something.text_tests.txt:    - export ${MY_PROJECUPPER_CASE}_IMAGE=${MYISTRY}/${MY_PROJECT_PATH}/${MY_PROJECT_NAME}:${VERSION} something.text_tests.txt:    - docker pull ${MY_REG}/${MY_PR}/${MY_PROJEC}:${VERS}

【问题讨论】:

    标签: linux bash sed grep


    【解决方案1】:

    试试

    grep -Po '\$\.*.[{_A-Z}]+' output.txt
    
    • -P 使用 Perl 语法生成 grep
    • -o 只输出匹配的部分

    现在,改进您的正则表达式。对于初学者,我已经添加了_,但它仍然会找到${X}{Y}(误报)或找不到${lowercase}(误报)并且只是部分找到${DIR#/}(因为额外的语法)。

    【讨论】:

    • 非常感谢,它对我有用。只是一个问题,这样的变量EXAMPLE_EXAMP_EXMP怎么样?有什么办法可以输出这个吗?
    • 如果它前面有$ 或包裹在${} 中,它将被找到。否则,例如查找变量赋值的 LHS 不是正则表达式的任务。
    • 这里实际上不需要-P 选项。正则表达式相当不精确,但使用 Perl 您可以 使其非常精确。不过,您确实需要一个解析器来正确解决这个问题。
    • 没错。我把它留给了-P 选项,以提供在这条道路上需要的惰性评估功能,但如果你足够关心精度,最终它是一个死胡同。
    【解决方案2】:

    您可以使用--only-matching 或简单地-o 告诉grep 仅输出匹配的部分。 这里真正的问题是真正使变量标识符有效的原因。这当然取决于脚本是为哪个 shell 编写的,以及脚本的原始作者使用了多少不同的样式。

    让我们假设一些理智的事情,标识符以 [a-Z] 开头,并且只能包含字母数字字符和下划线。您还可以使用$MY_VARIABLE${MY_VARIABLE} 引用相同的标识符。

    我会选择这样的:

    grep -rhIo '\$[a-zA-Z_\{\}]*' directory | sort --unique
    

    但请注意,变量上方的数组和操作的语法会很快破坏这一点。

    【讨论】:

      【解决方案3】:

      要获得${adjacent}text 的正确结果,可以选择

      grep -hrEo '\$\{?[A-Za-z_0-9]+\}?' .
      

      这仍然无法正常工作

      : <<\_
      literal $text in a quoted here document
      _
      echo '$quoted literal text'
      echo \$escaped \$dollar \$signs
      etc
      

      但是为了快速而肮脏的尝试,也许只是忽略那些极端情况,或者添加某种后处理来删除它们。 正确解决这个问题需要你有一个sh 解析器来找出引用了哪些美元符号等;和eval,即使这样也不完整。

      作为对此处其他答案的评论,grep -P 不可移植,并且需要 GNU grep。如果你没有这个,并且真的需要 Perl 正则表达式扩展,也许只需使用 Perl。

      perl -lne 'print($&) while m/\$\{?[A-Za-z_0-9]+\}?/go' **/*
      

      **/* 递归通配符也不是可移植的;如果你需要一个 POSIX 兼容的脚本,也许可以求助于

      find . -type f -exec \
          'print($&) while m/\$\{?[A-Za-z_0-9]+\}?/go' {} +
      

      当然 Perl 也不是 POSIX。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-04
        • 1970-01-01
        • 2014-08-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多