Linux

為什麼我需要在`compgen -G … |中使用-I參數xargs 基本名稱?

  • March 21, 2022

我遇到了一種情況,我正在管道輸出compgen -Gtoxargs 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 basenameandxargs -I{} basename {}是彼此的同義詞,但顯然它們不是。有什麼區別?

我懷疑它是否重要,但以防萬一:這發生在 Ubuntu 20.04.4(5.13.0-35-generic)上執行的 bash 5.0.17(1)-release 上。

我知道還有其他方法可以生成此文件列表,但我很擔心,因為我顯然不了解這裡需要了解的基本內容,以避免將來出現錯誤。

POSIXbasename一次只處理一個名稱,可以選擇刪除後綴。xargs basename嘗試一次執行basename盡可能多的參數,但失敗了;xargs -I{} basename {}導致每個名稱xargs執行basename一次以進行處理。

比較輸出

printf "foo\nbar\nbaz" | xargs echo basename

printf "foo\nbar\nbaz" | xargs -I{} echo basename {}

GNUbasename支持幾個選項來允許多個名稱;如果您不需要指定後綴:

xargs basename -a

如果你這樣做了,

xargs basename -s .suffix

引用自:https://unix.stackexchange.com/questions/696271