【问题标题】:Bat/Cmd vs. Sh/Bash arguments "stat"-like expansionBat/Cmd 与 Sh/Bash 参数“stat”-like 扩展
【发布时间】:2021-09-14 15:33:30
【问题描述】:

尝试将我的旧 bat (batch) 文件转换为 sh (bash) 但仍有一些问题我仍然无法找到 sh 等效(for delims tokens 为一)。

最值得注意的是,在 bat 中发现了非常漂亮的参数扩展:

https://ss64.com/nt/syntax-args.html
http://cplusplus.bordoon.com/cmd_exe_variables.html

%~I         - expands %I removing any surrounding quotes (")
%~fI        - expands %I to a fully qualified path name
%~dI        - expands %I to a drive letter only
%~pI        - expands %I to a path only
%~nI        - expands %I to a file name only
%~xI        - expands %I to a file extension only
%~sI        - expanded path contains short names only
%~aI        - expands %I to file attributes of file
%~tI        - expands %I to date/time of file
%~zI        - expands %I to size of file
%~$PATH:1   - searches the directories listed in the PATH
            environment variable and expands %1 to the
            fully qualified name of the first one found.
            If the environment variable name is not
            defined or the file is not found by the
            search, then this modifier expands to the
            empty string.

The modifiers can be combined to get compound results:

%~dpI       - expands %I to a drive letter and path only
%~nxI       - expands %I to a file name and extension only
%~fsI       - expands %I to a full path name with short names only
%~dp$PATH:1 - searches the directories listed in the PATH
            environment variable for %1 and expands to the
            drive letter and path of the first one found
            (but this would work only in called functions and
            only for numbered variables)
%~ftzaI     - expands %I to a DIR like output line

因此对于C:\Users\dkoch\Downloads\test.bat,您会得到:

%~0 : test.bat
%~f0 : C:\Users\dkoch\Downloads\test.bat
%~d0 : C:
%~p0 : \Users\dkoch\Downloads\
%~n0 : test
%~x0 : .bat
%~s0 : C:\Users\dkoch\DOWNLO~1\test.bat
%~a0 : --a--------
%~t0 : 14/09/2021 17:58
%~z0 : 351
%~$PATH:1 :
%~dp0 : C:\Users\dkoch\Downloads\
%~nx0 : test.bat
%~fs0 : C:\Users\dkoch\DOWNLO~1\test.bat
%~dp$PATH:1 :
%~ftza0 : --a-------- 14/09/2021 17:58 351 C:\Users\dkoch\Downloads\test.bat

如果可以的话,我经常使用%~f1 之类的东西来尝试将第一个参数扩展为完整路径。否则,参数保持不变并按原样传递。

sh中是否有类似$~f1这样方便的东西?

到目前为止,我发现的所有内容都是变量子字符串提取/替换:

http://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Shell-Expansions
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
https://linuxhint.com/bash_parameter_expansion/
https://wiki.bash-hackers.org/syntax/pe

对我正在尝试做的事情没有帮助。你的选择?

问候。

【问题讨论】:

  • 现在这个问题的提问方式只有 bash和bat都懂的人才可以回答。
  • 你能以一种不假设读者知道%~f1 的意思的方式来写它吗?
  • (...如果只是将相对路径变成绝对路径,这就是 readlink -frealpath 的用途)。
  • 关键是那些不是你的人不知道“至少蝙蝠做什么”,所以我们不能告诉你什么要求。鉴于上面评论中的猜测,听起来自己并不完全知道“至少蝙蝠做什么”。
  • AFAIK,@Socowi 的答案应该完全解决您的问题,但如果没有,也许您可​​以/应该评论它,描述它如何以及为什么没有?

标签: bash batch-file parameter-expansion


【解决方案1】:

参数扩展 [...] sh 有没有这么方便的东西

不,在大多数情况下,您必须依赖命令,而不是内置扩展。例如,而不是%~XYfile 你会写类似

$(cmd-that-does-X "$file"; cmd-that-does-Y "$file")

对于%~X…cmd-that-does-X 之间的翻译,请搜索 »How to do X in sh«。所有在 Unix 系统上有意义的X 应该已经有很多好的答案了。

但请记住,100% 等效翻译通常是不合理的(例如,Windows 用户期望不区分大小写的路径,而 Unix 用户期望区分大小写的路径)或者根本不可能(例如,Unix 没有驱动器号或短名称)。

%~f1 的示例

在 bash 脚本中,您可以将 %~f1 替换为

"$(realpath -m "$1")"

"$(readlink -m "$1")"

两者都不完全等同于%~f1,但它们的功能符合 Unix 用户的期望。 %~f1 内部使用FindFirstFileW;感谢@Mofi 指出这一点。如果你真的,真的想模仿这种行为,你至少(!)必须

  • 扩展 Windows (!) 通配符(注意 Windows 和 Unix 使用不同的通配符)
  • 以不区分大小写的方式(对于 Unix 来说非常不寻常)
  • 不解析符号链接
  • 但仍将./../ 标准化。

替换函数

如果您愿意,您可以编写一个为您翻译%~... 的函数。然后你会写 $(winexp abc "$1") 这样的东西,而不是 %~abc1

但是,我建议不要这样做。

  • 您可能不需要在单个脚本中进行所有扩展,因此将这个函数包含到所有脚本中是不必要的。
  • 至少对于 Unix 用户来说,winexp f "$1"realpath -m "$1" 更神秘/更不可读。
  • 对于组合扩展(例如 %~XYZ…),可能会有更高效的单个命令(例如 cmd-XYZ … 而不是 cmd-X …; cmd-Y …; cmd-Z …)。

【讨论】:

  • @Squashman 谢谢,我读了这么多。我所说的“不完全确定” 的意思是所有细节,例如区分大小写、通配符和(缺少的)扩展名。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-19
相关资源
最近更新 更多