【问题标题】:Convert a Filepath string into a Filepath/Directory in Bash将文件路径字符串转换为 Bash 中的文件路径/目录
【发布时间】:2020-04-14 23:34:42
【问题描述】:

我正在尝试制作一个简单的脚本,从一些纯文本模板创建文件。
具体来说,该脚本使用sed 解析和替换某些文件的内容,并使用awk 从模板本身获取应该写入生成文件的文件路径。

不幸的是,awk 获取的文件路径是一个字符串,所以当我使用重定向运算符“>”将sed 输出写入文件路径变量时,shell 给我这个错误:

./script.sh: line 45: ~/path/to/file/generatedFile: No such file or directory


一些脚本代码

// CSDdir:~/path/to/file/generatedFile

* {
    margin:                     0;
    spacing:                    0;
    border:                     0;
    text-color:                 <fg>;
    background-color:           transparent;
    border-color:               <bg>;
...

模板的第一行。

...

# Dirs
CUR_DIR=$( dirname "$(readlink -f "$0")" )
TEMPLATES_DIR="$CUR_DIR/templates"

...

tempDir=$( awk -F':' '$1 == "// CSDdir" { print $2; exit }' "$TEMPLATES_DIR/templateFile" )

cat "$TEMPLATES_DIR/templateFile" | sed \ # this is line 45
-e "s/<font>/$font/g" \
-e "s/<fg>/$foreground/g" \
-e "s/<bg>/$background/g" \
-e "s/<color0>/$color0/g" \
-e "s/<color8>/$color8/g" \
-e "s/<color1>/$color1/g" \
-e "s/<color9>/$color9/g" \
-e "s/<color2>/$color2/g" \
-e "s/<color10>/$color10/g" \
-e "s/<color3>/$color3/g" \
-e "s/<color11>/$color11/g" \
-e "s/<color4>/$color4/g" \
-e "s/<color12>/$color12/g" \
-e "s/<color5>/$color5/g" \
-e "s/<color13>/$color13/g" \
-e "s/<color6>/$color6/g" \
-e "s/<color14>/$color14/g" \
-e "s/<color7>/$color7/g" \
-e "s/<color15>/$color15/g" \
> $tempDir 

awk 从 templateFile 获取文件路径并将其放入 tempDir
sed 用值替换“标签”并写入输出在 tempDir 文件路径中,但它给了我之前提到的错误。

有没有办法将tempDir的内容转换成文件路径/目录?
或者,有没有办法用其他方法做同样的事情?

【问题讨论】:

  • Shell 没有字符串以外的任何类型。你是如何设置TEMPLATES_DIR 的。我怀疑您使用了TEMPLATES_DIR="~/..." 之类的东西,在这种情况下,~ 从未扩展到您的主方向。 TEMPLATES_DIR=~/"..." 是正确的(假设完全需要引号)。
  • 这是我设置该变量的方式`# Dirs CUR_DIR=$( dirname "$(readlink -f "$0")" ) TEMPLATES_DIR="$CUR_DIR/templates" `
  • 请在每个代码前写-sn-p 文件名。令人困惑的是:这是从哪里来的:~/path/to/file/generatedFile。在您提供的代码-sn-p 中,没有~/path/to/file/generatedFile。在错误消息中有./script.sh: line 45:。但是由于不知道哪个文件是script.sh。因此,我们无法查看第 45 行来查看错误发生在哪一行。
  • @AedvaldTseh 你说得对,我现在正在更新问题。
  • @chepner 你完美地解决了问题,错误是~。我自己找到了一个解决方案,将 tempDir 中的 ~ 替换为 $HOME 和转义字符。非常感谢!

标签: bash awk sed scripting


【解决方案1】:

问题正如 chepner 所建议的那样, ~ 没有被扩展。

这就是问题所在:

// CSDdir:~/.scripts/templates/generatedFile

考虑这样写:

// CSDdir:/absolute-path-to-home/.scripts/templates/generatedFile

也就是说,如果您想要一个更通用的解决方案,您必须告诉您的 bash 脚本来扩展变量。这可以(危险地)使用 eval 来完成。您还可以使用 python 函数os.path.expanduser 执行波浪号扩展。

考虑如下替换最后一行:

>$(python -c "import os.path ; print  os.path.expanduser('$tempdir') ")

上面的行假设python2。

如果您信任 CSDir 评论的作者,您可以使用这样的 eval:

> $( eval "echo $tempdir" ) 

【讨论】:

  • 这也是一个有效的解决方案。谢谢!
【解决方案2】:

感谢@chepner,我自己找到了解决方案。
问题是~ 字符被awk 占用时,它不会“扩展”到主目录。

更简洁的解决方法是将 tempDir 中的 ~(如果存在)替换为 $HOME 值和 \ 字符:

home=$( echo $HOME | sed 's/\//\\\//g')
tempDir=$( awk -F':' '$1 == "// CSDdir" { print $2; exit }' "$TEMPLATES_DIR/rofiConfig" | sed -e "s/~/$home/g" )

现在,一切正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-07
    • 1970-01-01
    • 2012-11-23
    • 2012-01-25
    • 2016-03-04
    • 1970-01-01
    • 2013-05-18
    • 2016-12-11
    相关资源
    最近更新 更多