我想在脚本中使用
sed
来修改现有文件的内容。我有一条这样的线...
sed -i '' 's/${scripts}/${newScripts}/' "$packpath"
...它并没有像我想象的那样在我的 Mac 上完成。如果您能提供任何帮助来纠正此行,我将不胜感激。
在我的 Mac 上,我在
~/.zshrc
创建了一个脚本,其中包含以下行:
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
我在
~/.bash_aliases
有一个脚本,其中包含许多别名和函数来处理常见任务。
我经常使用
gh-pages
Node 模块创建想要部署到 GitHub 的小型 React 项目。此过程的一个步骤是将两行添加到名为 package.json
. 的文件中。
为简单起见,在添加任何行之前,我们假设
package.json
文件如下所示。
{
"name": "react-project",
"scripts": {
"dev": "vite",
"build": "vite build"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
之后,它应该看起来像这样:
{
"name": "react-project",
"scripts": {
"dev": "vite",
"build": "vite build",
"predeploy": "npm run build",
"deploy" : "gh-pages -d dist"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
我添加到我的
.bash_aliases
的功能目前看起来像这样:
ghdeploy() {
package="package.json"
packpath="$PWD/$package"
packtext=`cat $packpath`
deploy_it=",\\n \"predeploy\": \"npm run build\",\\n \"deploy\" : \"gh-pages -d dist\"\n "
setopt local_options BASH_REMATCH
regex='"scripts":[^\}]+'
if [[ "$packtext" =~ "$regex" ]]; then
scripts=$BASH_REMATCH[1] ## includes final \n\s\s
if [[ "$scripts" =~ ("deploy": "\w+") ]]; then
echo "package.json already contains deploy script"
else
chunk=${scripts:0:-3} ## remove final \n\s\s
newScripts="$chunk$deploy_it"
echo "newScripts: $newScripts"
sed -i '' 's/${scripts}/${newScripts}/' "$packpath"
fi
else
echo "scripts not found"
fi
}
第
echo "newScripts...
行打印出我想要进行的更改,但第 sed -i '' ...
行不会将这些更改应用到我的文件。
我不明白的是什么?
sed
不太可能是正确的工具,因为您可能想要文字字符串替换,但sed
不理解文字字符串,请参阅is-it-possible-to-escape-regex-metacharacters-reliously -with-sed。这将使用任何 awk
: 完成你想要的事情
$ cat tst.sh
#!/usr/bin/env bash
ghdeploy() {
local package packpath tmp
tmp=$(mktemp) || exit
trap 'rm -f "$tmp"; exit' EXIT
package='package.json'
packpath="$PWD/$package"
awk '
BEGIN {
deploy_it = ",\n \"predeploy\": \"npm run build\",\n \"deploy\" : \"gh-pages -d dist\"\n"
}
/"scripts": \{/ {
inScripts = 1
}
inScripts {
if ( $1 ~ /^}/ ) {
if ( scripts ~ /"deploy"/ ) {
printf "%s already contains deploy script\n", FILENAME | "cat>&2"
$0 = scripts
}
else {
$0 = scripts deploy_it $0
}
inScripts = 0
}
else {
scripts = (scripts == "" ? "" : scripts ORS) $0
next
}
}
{ print }
END {
if ( inScripts == "" ) {
print "scripts not found" | "cat>&2"
}
}
' "$packpath"
#' "$packpath" > "$tmp" && mv -- "$tmp" "$packpath"
}
ghdeploy
$ ./tst.sh
{
"name": "react-project",
"scripts": {
"dev": "vite",
"build": "vite build",
"predeploy": "npm run build",
"deploy" : "gh-pages -d dist"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
完成测试并对输出感到满意后,只需将
' "$packpath"
替换为 ' "$packpath" > "$tmp" && mv -- "$tmp" "$packpath"
。