![如何替换变量输出中包含的文件内容](https://linux22.com/image/185530/%E5%A6%82%E4%BD%95%E6%9B%BF%E6%8D%A2%E5%8F%98%E9%87%8F%E8%BE%93%E5%87%BA%E4%B8%AD%E5%8C%85%E5%90%AB%E7%9A%84%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B9.png)
我已经搜索了变量语法和其他命令,但无法通过。
我有一些使用 btrfs 快照创建的文件夹。在每个文件夹中都有一个名为的文件/etc/fstab
,我需要编辑该文件并将其始终替换为文件夹路径中的值。例如我替换@
为@snapshots/daily/root2020-12-27_19H05
这里的变量2020-12-27_19H05
总是以 为前缀root
。
在开始编辑文件之前,第一步是做一些简单的事情,例如制作一个简单的 bash 脚本,该脚本在变量找到的每个文件夹中创建一个文件作为根目录,我有:
cd /.snapshots/daily
SNAPSHOTS=$(ls -d root*/)
echo > $SNAPSHOTS/test
但我收到以下错误:
bash: $SNAPSHOTS/test: ambiguous redirect
我在我能想到的每个位置尝试了“”、''、()、{} 的各种方法,但都失败了。我在某些地方尝试使用 SUDO 但也失败了。这在互联网上似乎很常见,但我读到的内容并没有让我理解并解决我的问题。
我究竟做错了什么?
谢谢!
答案1
可能SNAPSHOTS
包含多个目录。
set -x
当您在命令前插入一行时,您可以看到问题echo
。这将显示$SNAPSHOTS
.
使用循环echo
为每个匹配的目录调用该命令。
for i in root*/
do
if [ "$i" != 'root*/' ]
then
touch "$i"/test
fi
done
如果没有匹配的目录,附加程序if
会避免运行。touch 'root*/test'
答案2
您的SNAPSHOTS
变量包含空格。要重定向到其值,请双引号它:
echo > "$SNAPSHOTS"/test
这很可能不会做你想要的事情,因为你似乎想在SNAPSHOTS
.您不能将多个单独的字符串存储在一个字符串中,并认为您可以从该单个字符串中正确检索它们。它实际上应该是一个数组并且ls
你在这里根本不需要:
shopt -s nullglob
SNAPSHOTS=(root*/)
for snap in "${SNAPSHOTS[@]}"; do
echo >"$snap"/test
done
要不就
shopt -s nullglob
for snap in root*/; do
echo >"$snap"/test
done
设置nullglob
shell 选项可确保模式在不匹配任何内容时被完全删除。如果没有nullglob
,则如果模式不匹配任何内容,则模式将按原样保留。
如果您想在其中放入空行的文件不多,您也可以这样做
shopt -s nullglob
SNAPSHOTS=(root*/)
echo | tee "${SNAPSHOTS[@]/%//test}" >/dev/null
如果你真的只是想创造文件(不要在其中写入空行),然后使用touch
:
shopt -s nullglob
SNAPSHOTS=(root*/)
touch "${SNAPSHOTS[@]/%//test}" 2>/dev/null
答案3
你们知道一切并解释答案,以便我们能够理解,这个网站是一个令人难以置信的数据库。
最后我去了
for i in root*/
do
if [ "$i" != 'root*/' ]
then
sudo touch "$i"/test
fi
done
此处使用 sudo 因为这些快照文件夹归 root 所有。
所以现在我明白了我的第一步,即在变量内返回的文件夹列表中的文件上创建、重命名、删除、更改权限等。
我现在更进一步,即在变量返回的每个文件夹中编辑一个文件,并将固定值替换为等于变量一开始返回的值的变量值。
我无法理解如何将变量集成到我想要替换的值中。
我更改了快照结构以使脚本更容易(对我来说)。因此,现在列出文件夹中所有文件夹的变量返回以下内容:
echo $SNAPSHOTS
2020-12-22_19H05/
2020-12-23_19H05/
2020-12-24_19H05/
2020-12-25_19H05/
2020-12-26_19H05/
2020-12-27_19H05/
2020-12-28_19H05/
在每个目录名称每天都会更改的文件夹中(最旧的一天被删除,今天被添加),有一个文件位于 /etc/fstab,作为2020-12-22_19H05/etc/fstab
示例。
我需要编辑该文件,搜索固定值“@home”并将其替换为固定前缀字符串的变量值部分,例如:
@snapshots/daily/home/$VARIABLE
$VARIABLE = 上面列出的第一个变量返回的目录名称。
因此,在文件夹内,2020-12-22_19H05/
文件/etc/fstab
将被编辑以替换@home
为末尾@snapshots/daily/home/2020-12-22_19H05
没有的/
,需要省略/截断。对于第一个变量找到的所有文件夹依此类推。
我期待 sed 和可能的 % 被使用,但我真的不知道在互联网上搜索什么才能 1-得到答案,但主要是 2-理解答案。
谢谢!