Shell

以任一順序回顯包含“a”和“b”的文件名

  • May 11, 2022

我有一個文件列表如下:

$ echo *
add akfefg aka ab ba

我想以任一順序回顯包含“a”和“b”的文件名。我試過了

echo *[ab]*[ba]*
aka ab ba

它還列印“aka”。我試過了

$ echo *a*b* && echo *b*a*
ab
ba

它完成了它的工作,但“ba”列印在下一行。有沒有更簡單的方法來做到這一點?謝謝你。

在這個答案中,我解決了兩種不同的情況:

  1. 您想匹配目前目錄中同時包含a和的文件名,然後您想對這些文件做一些事情b
  2. 您想要處理兩個echo命令的輸出以刪除換行符。

如果您想遍歷文件名,那麼最好有一個匹配所有名稱的單一模式,然後在循環中使用該模式的擴展。echo不建議使用,因為這消除了各個文件名之間的區別。

zshshell 中,單一模式(*a*b*|*b*a*)將擴展到字母ab以任何順序出現的所有名稱。

bashshell 中,您可以使用單個擴展通配模式(或類似通ksh配模式)@(*a*b*|*b*a*)來做同樣的事情。預設情況下bash,shell 不啟用擴展通配模式,因此您需要先啟用這些模式shopt -s extglob

因此,在bash外殼中,您可以使用類似

shopt -s extglob

for name in @(*a*b*|*b*a*); do
   # process "$name" here
done

生成所需文件名進行處理的另一種方法是使用find

find . ! -name . -prune -name '*a*' -name '*b*'

這會(僅)在目前目錄中查找包含a和的任何名稱b。然後,您將-exec在此命令末尾呼叫其他一些實用程序來執行操作,例如使用

find . ! -name . -prune -name '*a*' -name '*b*' -exec sh -c '
   for name do
       # process "$name" here
   done' sh {} +

在這裡,find生成內嵌sh -c腳本使用的文件名。另請參閱了解 find 的 -exec 選項

但是,如果這是一個文本處理練習,並且目的是將兩行或多行文本(兩次echo呼叫的輸出)排列成一行,那麼您可以通過paste -s -. 這將另外刪除嵌入文件名中的任何換行符。以paste這種方式使用而不是tr -d '\n'(也刪除換行符)確保生成的文本在末尾由單個換行符終止。

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