compgen -G
aの出力をパイピングしましたが、xargs basename
以下のようにパラメータを追加するまで機能しない状況が発生しました。xargs -I
以下は、コメントと一緒に私がしたいことを示すスクリプトです。 2つの質問があります。その質問はスクリプトの後ろに表示されます。
# create three files for testing:
touch /tmp/my.file.1.2.txt
touch /tmp/1.my.file.2.txt
touch /tmp/1.2.my.file.txt
# create a glob and verify that it works with compgen:
glob=/tmp/*.file*.txt
compgen -G "$glob"
#output:
/tmp/1.2.my.file.txt
/tmp/1.my.file.2.txt
/tmp/my.file.1.2.txt
# try to get the basename of each file using xargs.
# I thought this would work, but it does not.
compgen -G "$glob" | xargs basename
#output:
basename: extra operand ‘/tmp/my.file.1.2.txt’
Try 'basename --help' for more information.
# eventually I discovered that this would work.
# however, I don't understand why this would work
# but the previous attempt would not, since I
# think that this command is just a more
# explicitly-specified version of the previous
# one.
compgen -G "$glob" | xargs -I{} basename {}
#output:
1.2.my.file.txt
1.my.file.2.txt
my.file.1.2.txt
xargs
他のコマンドはパラメータなしで使用できます-I
。例えば、それはcompgen -G "$glob" | xargs ls -al
素晴らしい作品です。
basename
Q1:このスクリプトに必要なパラメータは何ですか-I
?
質問2:この結果を見る前に、私はお互い同義語だと思いましたが、そうではありませんxargs basename
。xargs -I{} basename {}
違いは何ですか?
これが問題になるかどうか疑問ですが、もしそうなら、この問題はbash 5.0.17(1)リリースを実行するUbuntu 20.04.4(5.13.0-35-generic)で発生します。
このファイルのリストを生成する他の方法があることはわかっていますが、将来のエラーを防ぐために理解する必要がある基本をここで明らかに理解していないので心配です。
答え1
POSIXbasename
一度に1つの名前のみが処理され、オプションでサフィックスを削除します。一度にできるだけ多くの引数を実行しようとしましたxargs basename
が、失敗して処理のために各名前が一度実行されます。basename
xargs -I{} basename {}
xargs
basename
出力比較
printf "foo\nbar\nbaz" | xargs echo basename
そして
printf "foo\nbar\nbaz" | xargs -I{} echo basename {}
GNUは、basename
サフィックスを指定する必要がない場合に複数の名前を受け入れる複数のオプションをサポートしています。
xargs basename -a
これにより、
xargs basename -s .suffix