我正在开发一个 bash 脚本,它将使用通配符路径搜索特定文件,一旦找到该文件名,它就会在文件中搜索特定术语,然后替换它。
这是我已经整理好的:
#!/bin/sh
PATH=${1}
FILENAME="$2"
SEARCHFOR="$3"
/usr/bin/clear
echo "Searching $PATH"
echo "For the file $FILENAME"
echo "With the string $SEARCHFOR"
echo "=========================="
echo " RESULTS "
echo "=========================="
/usr/bin/find $PATH -type f -name "$FILENAME" | /usr/bin/xargs /bin/grep -l "$SEARCHFOR"
我还没有添加替代品,但我想我会使用 SED 而不是 grep 来做到这一点,只是为了测试目的使用 grep。
对于上面的代码,我必须对任何类型的通配符路径使用引号。有解决办法吗?
./script '/home/*/public_html' php.ini module.so
我在想也许可以使用参数,但必须有另一种方法来做到这一点。
我的最终目标是有一个 bash 脚本,我可以将通配符路径或文件名传递给它,它将搜索该文件,一旦找到该文件,它就会搜索特定的术语并在找到时替换它。
听起来很简单,它应该是这样,但我正在用头撞 table ,因为我已经很久没有弄乱 bash 了……aaggghh 帮助!
最佳答案
首先,以大写形式声明变量名是一个糟糕、糟糕、非常糟糕的主意,尤其是 PATH
因为您实际上会重新设置实际的 PATH
环境变量(只需在提示中执行 echo $PATH
,您就会明白我的意思,这可能是您必须使用 /usr/bin/的原因之一clear
而不是 clear
因为环境变量 PATH
被修改了)。因此,始终建议使用小写变量,例如 path
。
您面临的问题是子 shell 中 *
的 glob
扩展。当你使用
./script '/home/*/public_html' php.ini module.so
*
不会在提示符(父 shell)中展开,而是在脚本的子 shell 中展开。但是当你使用
./script /home/*/public_html php.ini module.so
*
在父 shell 中展开(这将导致 shell 指向一个随机路径),然后在程序子 shell 中传递-
假设,/home
有目录/user
、/apps
、/data
做$ cd *
会将您带到按字母顺序排在第一位的目录,即 /apps
。所以 /home/*
在父 shell 中没有引号将始终指向 /home/apps
这不是我们想要的!
解决方法如下
$set -o noglob #unset glob expansion
$./script /home/*/public_html php.ini module.so #your command without quotes & wildcard */
$set +o noglob #re-set glob expansion back
或
$set -o noglob;./script /home/*/public_html php.ini module.so;set +o noglob
尝试 $echo *
然后是 $set -o noglob;echo *;set +o noglob
作为一个简单的例子。
警告- 如果您失败或忘记设置 noglob
(set +o noglob
),shell 将像 >*
和 ?
像普通字符一样,不会扩展它们,这可能会导致不良结果和混淆。
关于linux - Bash 脚本搜索文件并在使用通配符在文件中找到字符串时替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12309601/