Gnu-Parallel

並行和 ls 帶空格

  • November 28, 2021

此命令適用於具有“正常”名稱的 dir1 mydir my-dir 等

ls | parallel 'echo -n {}" "; ls {}|wc -l'

給我每個目錄的文件數

但是對於帶有空格的目錄,例如“我的目錄”或我的長目錄名稱,它不起作用並給出錯誤。

如何引用/轉義空格?

parallel沒有, xargs, 或來回傳遞路徑名的複雜性:

shopt -s nullglob dotglob

for dir in */; do
   set -- "$dir"/*
   printf '%s:\t%s\n' "${dir%/}" "$#"
done

也就是說,遍歷所有目錄併計算*glob 在每個目錄中擴展的名稱數量。

以上是針對 的bash,我們設置了nullglobshell 選項以確保不匹配的模式被移除而不是保留未擴展。我還將dotglobshell 選項設置為能夠匹配隱藏的名稱。

shell 可以這樣zsh做,同時只過濾目錄(對於循環)和例如正常文件(對於循環體)的全域匹配。在下面的程式碼中, glob 限定符(ND/)使前面的只匹配目錄,效果與shell中的*withnullglobdotglobset相同,並使前面的只匹配正常文件。bash``(ND.)``*

for dir in *(ND/); do
   set -- $dir/*(ND.)
   printf '%s:\t%s\n' $dir $#
done

您是否想遞歸地執行此操作,以獲取層次結構中每個目錄中的名稱計數,然後您可以將上面的內容插入find

find . -type d -exec bash -O nullglob -O dotglob -c '
   for dir do
       set -- "$dir"/*
       printf "%s:\t%s\n" "$dir" "$#"
   done' bash {} +

bash(以上內容與此答案開頭的普通循環有點不同,因為這永遠不會計算通過符號連結訪問的目錄中的名稱),或者,

find . -type d -exec zsh -c '
   for dir do
       set -- $dir/*(ND.)
       printf "%s:\t%s\n" $dir $#
   done' zsh {} +

GNU Parallel 處理空格沒有問題:

$ mkdir 'a  b'
$ touch 'a  b/c  d'
$ ls | parallel 'echo -n {}" "; ls {}|wc -l'
a  b 1

如果名稱包含 \n,則它需要-0

$ mkdir 'a

b'
$ touch 'a

b/c

d'
# fails
$ ls | parallel 'echo -n {}" "; ls {}|wc -l'
$ parallel 'echo -n {}" "; ls {}|wc -l' ::: *
# works
$ printf "%s\0" * | parallel -0 'echo -n {}" "; ls {}|wc -l'
$ parallel -0 'echo -n {}" "; ls {}|wc -l' ::: *

所以你看到的可能是因為你ls做了一些奇怪的事情:它可能是ls --some-weird-option. 嘗試\ls代替(或使用printf ... | ... -0or-0 ... ::: *如上所示):

\ls | parallel 'echo -n {}" "; ls {}|wc -l'

(PS:你知道嗎--tag

parallel --tag 'ls {}|wc -l' ::: *

)

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