我遇到了许多带有变量的shell脚本,我一直认为存在严重的误解.我的理解是,按照惯例(也许很久以前就必须),环境变量都是全部的.
但是在像Bash这样的现代脚本环境中,我总是倾向于使用临时变量的小写名称约定,而仅为导出(即环境)变量使用大写的约定.例如:
#!/usr/bin/env bash
year=`date +%Y`
echo "It is $year."
export JAVA_HOME="$HOME/java"
Run Code Online (Sandbox Code Playgroud)
这一直是我对事物的看法.是否有任何权威来源同意或不同意这种方法,还是纯粹是风格问题?
如果我从脚本运行这些命令:
#my.sh
PWD=bla
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
xxx
bla
Run Code Online (Sandbox Code Playgroud)
没事.
但是,如果我跑:
#my.sh
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
$ sed: -e expression #1, char 8: Unknown option to `s'
Run Code Online (Sandbox Code Playgroud)
我在教程中读到要替换你需要停止的shell中的环境变量,并且"引用"该$varname部分以便它不直接替换,这就是我所做的,并且只有在之前定义变量时才有效.
我怎样才能将sed识别$var为在shell中定义的环境变量?
我正在尝试使用
sed -i -e "s/.*seb.*/ \"$ftp_login_template\"/" $ftp_dir
Run Code Online (Sandbox Code Playgroud)
但是我收到这个错误:
sed: -e expression #1, char 34: unknown option to `s'
Run Code Online (Sandbox Code Playgroud)
我不明白为什么因为这完美地工作:
sed -i -e "s/.*wbspassword.*/ \"wbspassword\": \"$password\",/" $user_conf
Run Code Online (Sandbox Code Playgroud)
关于我做错了什么的任何想法?
这可能是问题吗?
ftp_login_template=\${user}:${password}:24:86::\/var\/lib\/clit.${user}\/downloads:\/bin\/false\"
我一次又一次地看到Bash在Stack Overflow上使用eval的答案,并且答案得到了抨击,双关语是为了使用这种"邪恶"结构.为什么eval这么邪恶?
如果eval不能安全使用,我应该使用什么呢?
我想知道是否有可能编写一个100%可靠的sed命令来转义输入字符串中的任何正则表达式元字符,以便它可以在后续的sed命令中使用.像这样:
#!/bin/bash
# Trying to replace one regex by another in an input file with sed
search="/abc\n\t[a-z]\+\([^ ]\)\{2,3\}\3"
replace="/xyz\n\t[0-9]\+\([^ ]\)\{2,3\}\3"
# Sanitize input
search=$(sed 'script to escape' <<< "$search")
replace=$(sed 'script to escape' <<< "$replace")
# Use it in a sed command
sed "s/$search/$replace/" input
Run Code Online (Sandbox Code Playgroud)
我知道有更好的工具可以使用固定字符串而不是模式,例如awk,perl或python.我想证明是否有可能sed.我会说让我们专注于基本的POSIX正则表达式,以获得更多乐趣!:)
我已经尝试了很多东西,但任何时候我都能找到一个打破了我的尝试的输入.我认为保持它是抽象的,因为script to escape不会导致任何人走错方向.
顺便说一下,讨论在这里提出来了.我认为这可能是收集解决方案的好地方,可能会破坏和/或详细说明.
grep从命令行使用时不能输入"原始"字符串,因为某些字符需要转义才能被视为文字.例如:
$ grep '(hello|bye)' # WON'T MATCH 'hello'
$ grep '\(hello\|bye\)' # GOOD, BUT QUICKLY BECOMES UNREADABLE
Run Code Online (Sandbox Code Playgroud)
我printf用来自动转义字符串:
$ printf '%q' '(some|group)\n'
\(some\|group\)\\n
Run Code Online (Sandbox Code Playgroud)
这会生成字符串的bash-escaped版本,并且使用反引号,可以很容易地将其传递给grep调用:
$ grep `printf '%q' '(a|b|c)'`
Run Code Online (Sandbox Code Playgroud)
但是,它显然不适用于此:输出中的某些字符不会被转义,而有些则不必要.例如:
$ printf '%q' '(^#)'
\(\^#\)
Run Code Online (Sandbox Code Playgroud)
该^传递给角色时,不应该逃脱grep.
是否有一个cli工具,它接受一个原始字符串并返回一个bash-escaped版本的字符串,可以直接用作grep的模式?如果没有,我怎么能用纯粹的bash来实现呢?
用Bash和SED我试图用URL替换js文件中的两个字符串.
当我运行.sh脚本时,应插入的两个url是输入参数.
./deploy.sh https://hostname.com/a/index.html https://hostname2.com/test
Run Code Online (Sandbox Code Playgroud)
然而,为了使我的sed命令这可用我要逃避所有向前斜杠:\\?
./deploy.sh https:\\/\\/hostname.com\\/a\\/index.html https:\\/\\/hostname2.com\\/test
Run Code Online (Sandbox Code Playgroud)
如果它们被转义,则此SED命令适用于Mac OSX Sierra
APP_URL=$1
API_URL=$2
sed "s/tempAppUrl/$APP_URL/g;s/tempApiUrl/$API_URL/g" index.src.js > index.js
Run Code Online (Sandbox Code Playgroud)
现在我不想将转义的URL作为参数插入,我希望它自己的脚本能够转义正斜杠.
这就是我尝试过的:
APP_URL=$1
API_URL=$2
ESC_APP_URL=(${APP_URL//\//'\\/'})
ESC_API_URL=(${API_URL//\//'\\/'})
echo 'Escaped URLS'
echo $ESC_APP_URL
#Echos result: https:\\/\\/hostname.com\\/a\\/index.html
echo $ESC_API_URL
#Echos result: https:\\/\\/hostname2.com\\/test
echo "Inserting app-URL and api-URL before dist"
sed "s/tempAppUrl/$ESC_APP_URL/g;s/tempApiUrl/$ESC_API_URL/g" index.src.js > index.js
Run Code Online (Sandbox Code Playgroud)
参数看起来相同,但在这种情况下,SED会抛出错误
sed: 1: "s/tempAppUrl/https:\\/\ ...": bad flag in substitute command: '\'
Run Code Online (Sandbox Code Playgroud)
谁能告诉我这里的区别?字符串看起来相同,但给出不同的结果.
我有一个字符串,我想删除标点符号.
我开始了
sed 's/[[:punct:]]/ /g'
Run Code Online (Sandbox Code Playgroud)
但是我在HP-UX上遇到的问题一直不喜欢,有时我会得到一个0,而且$在我的字符串中的任何内容都会消失.所以我决定尝试手动完成.
我有以下代码,它适用于我感兴趣的所有标点符号,除了我似乎无法添加方括号"[]"到我的sed与其他任何东西,否则它不会替换任何东西,我不会得到一个错误,所以我不知道该解决什么问题.
无论如何,这是我目前拥有并想要添加[]的内容.
sed 's/[-=+|~!@#\$%^&*(){}:;'\'''\"''\`''\.''\/''\\']/ /g'
Run Code Online (Sandbox Code Playgroud)
顺便说一下,我在Solaris,Redhat和HP上使用KSH
我需要像这样运行一个sed命令作为shell脚本的一部分
sed's/brad/pitt/g'
我应该提供brad作为命令行参数并运行这样的命令
sed s/$ 1/pitt/g
虽然这个命令正在运行,但我想知道的是如何在不删除引号的情况下执行此命令,因为我可能在替换字符串中有一些需要引号的内容.
我对引号不太自信,这就是为什么我想通过一些调整来看看事情是如何工作的?