Linux
為什麼我需要在`compgen -G … |中使用-I參數xargs 基本名稱?
我遇到了一種情況,我正在管道輸出
compgen -G
toxargs basename
並且無法讓它工作,直到我添加瞭xargs -I
如下所示的參數。這是一個腳本,展示了我正在嘗試做的事情,並附有解釋性評論。我有兩個問題,它們出現在腳本之後。# create three files for testing: touch /tmp/my.file.1.2.txt touch /tmp/1.2.my.file.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
工作得很好。問題1:
basename
這個腳本中需要-I
參數的內容是什麼?問題2:在觀察到這個結果之前,我會認為
xargs basename
andxargs -I{} basename {}
是彼此的同義詞,但顯然它們不是。有什麼區別?我懷疑它是否重要,但以防萬一:這發生在 Ubuntu 20.04.4(5.13.0-35-generic)上執行的 bash 5.0.17(1)-release 上。
我知道還有其他方法可以生成此文件列表,但我很擔心,因為我顯然不了解這裡需要了解的基本內容,以避免將來出現錯誤。
POSIX
basename
一次只處理一個名稱,可以選擇刪除後綴。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