我想保存所有的变量在一个单独的文件中,删除重复的目录首先,我在一个单独的文件
中编写了所有带有全局变量的行。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}
Try
grep -Po '$.*.[{_A-Z}]+' output.txt
-P
使grep
使用Perl语法-o
只输出匹配部分
现在,改进您的正则表达式。对于初学者,我已经添加了_
到它,但它仍然会找到${X}{Y}
(假阳性)或不找到${lowercase}
(假阴性),只是部分找到${DIR#/}
(因为额外的语法)。
您可以使用--only-matching
或简单地-o告诉grep
只输出匹配的部分。这里真正的问题是什么才是有效的变量标识符。当然,这取决于脚本是为哪个shell编写的,以及脚本的原作者使用了多少种不同的风格。
让我们假设一些相同的东西,标识符以[a-Z]开头,只能包含字母数字字符和下划线。您也可以使用$MY_VARIABLE
或${MY_VARIABLE}
引用相同的标识符。
我会这样写:
grep -rhIo '$[a-zA-Z_{}]*' directory | sort --unique
但是要注意,数组和变量上面的操作的语法会很快打破这个规则。
要获得${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
是不可移植的,并且需要GNUgrep
。如果您没有这些,并且确实需要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。