修复 bash 脚本,当路径不以 / 结尾时,期望路径输入以 / 结束时会中断

修复 bash 脚本,当路径不以 / 结尾时,期望路径输入以 / 结束时会中断

我有这个代码:

for file in "$@"*png; do
  echo "$file"
done

仅当您提供以 / 结尾的路径时,它才有效/root/

在这种情况下,在不破坏我的脚本的情况下将 / 添加到路径输入的正确方法是什么?

如果你给出的路径输入末尾没有 / ,它只会执行以下操作:

File: /root*png

如果我将其修改为for file in "$@"/*png; do并输入/root/test/它可以工作,但结果看起来很难看:

File: /root/test//sample2.png

答案1

ilkkachu 指出了我的答案中的一个重大缺陷,并在他的答案中纠正了它,所以请给予他应得的信任。不过我想出了另一个解决方案:

#!/bin/bash

for dir in "$@"; do
        find "$dir" -type f -name '*png' -exec readlink -f {}  \;
done

例子:

$ ll
total 6
-rwxr-xr-x 1 root root 104 Jan  7 14:03 script.sh*
drwxr-xr-x 2 root root   3 Jan  7 04:21 test1/
drwxr-xr-x 2 root root   3 Jan  7 04:21 test2/
drwxr-xr-x 2 root root   3 Jan  7 04:21 test3/

$ for n in {1..3}; do ll "test$n"; done
total 1
-rw-r--r-- 1 root root 0 Jan  7 04:21 testfile.png
total 1
-rw-r--r-- 1 root root 0 Jan  7 04:21 testfile.png
total 1
-rw-r--r-- 1 root root 0 Jan  7 04:21 testfile.png

$ ./script.sh test1 test2/ test3
/root/temp/test1/testfile.png
/root/temp/test2/testfile.png
/root/temp/test3/testfile.png

原创解决方案:

for file in "${@%/}/"*png; do
  echo "$file"
done

${@%/} 会删除参数末尾的 / ,然后 / 外面的 / 会将其添加回来——或者将其添加到任何没有的参数中。

答案2

像这样使用$@glob 似乎有点奇怪。如果您期望它能够处理多个参数,那么它是行不通的。周围的字符串$@仅附加到第一个和列表项。

$ mkdir a b; touch a/a.png b/b.png
$ set -- a b 
$ echo x"$@"x
xa bx
$ echo "$@/"*.png
a b/b.png

因此,要处理多个参数,您需要"$@"单独循环:

for arg in "$@"; do
    for file in "${arg%/}"/*.png; do
         echo "$file"
    done 
done

在另一种情况下,您可以使用字符串替换扩展${//}(在 Bash 或 zsh 中)为每个位置参数添加后缀,但要使其与 glob 一起使用相当困难。

答案3

您也可以使用 tr。

始终在末尾添加 / 并...

file='/root/test//sample2.png';echo "$file" | tr -s '/'

相关内容