パスが/で終わらないために中断されたときにパス入力が/で終わると予想される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 '/'

関連情報