【问题标题】:Replace directory names in a path in ksh script替换 ksh 脚本中路径中的目录名称
【发布时间】:2019-09-24 09:29:06
【问题描述】:

我想从给定的绝对路径生成相对路径并将其存储在变量中。

/aaa/bbb/ccc/ddd/eee.txt 应该生成../../../..,我可以根据要求将其附加到其他路径。

$filepath=/aaa/bbb/ccc/ddd/eee.txt

我想创建一个名为$abs 的新变量,其中应包含../../../..。

试过这个:

echo "$filepath" | sed -r 's/*/../g'

上述模板不符合要求。

作为一个新手,我可能会问一些愚蠢的问题。

请原谅并提前感谢!

【问题讨论】:

  • 我不知道你会在abs=$(some_command)之后对${abs}做什么,使用这个相对路径会很棘手。难道你不想找到一个top_dir,相对于你的脚本,并表达相对于这个目录的一切(比如inifile="${top_dir}/cfg/project.ini")。

标签: string scripting ksh


【解决方案1】:

我不确定 sed 是否能够做到这一点,但可以显示一个 awk 命令来做到这一点。

echo "$filepath" | awk -F'/' '{ for ( i = 2; i < NF-1; i++ ) printf "../" } END{print ".."}'

在哪里 -F '/' 是字段分隔符 将文本 /aaa/bbb/ccc/ddd/eee.txt 分成 6 个部分,每个部分都可以用作 awk 中的变量,这也导致它在这种情况下从文本中删除字段分隔符 /。

  • $1 首先是 '' 为空/之前没有任何内容。
  • $2 是 aaa
  • $3 是 bbb
  • $4 是 ccc
  • $5 是 ddd
  • $6 是 eee.txt

NF 变量包含我们有多少字段。


for ( i = 2; i &lt; NF-1; i++ ) 用于循环

我从 2 而不是 1 开始,因为第一个字段始终为空,因为绝对路径始终以 / 开头,这将忽略该字段。

我还将NF 变量与1 作为最后一个字段相减,将包含文件名,因此它不是目录,但是如果它是目录并且没有/,则可能会出现问题在它的结尾像/home/jondoe 你将以.. 而不是../.. 结束,而/home/jondoe/ 将起作用。

printf "../" 在每个循环中彼此相邻打印,只要循环结束。

END{print ".."} 将打印..,无论输入发生了什么。这将导致 .. 在文本末尾,而 for 循环仅重复打印 ../


这个命令仍然可以改进以消除陷阱,就像我提到的那样。 我希望这能满足您的需求。

【讨论】:

    【解决方案2】:

    您可以避免使用另一个字符(例如 #)转义斜线。
    首先,您使用“${filepath%/*}”(优于basename)从路径中截取文件名。
    您将每个字符串替换为至少一个字符。
    最后删除起始斜线。

    echo "${filepath%/*}"| sed 's#[^/]\+#...#g;s#\/##'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-03
      • 1970-01-01
      • 2010-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-11
      相关资源
      最近更新 更多