Gnu-Parallel
並行和 ls 帶空格
此命令適用於具有“正常”名稱的 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
,我們設置了nullglob
shell 選項以確保不匹配的模式被移除而不是保留未擴展。我還將dotglob
shell 選項設置為能夠匹配隱藏的名稱。shell 可以這樣
zsh
做,同時只過濾目錄(對於循環)和例如正常文件(對於循環體)的全域匹配。在下面的程式碼中, glob 限定符(ND/)
使前面的只匹配目錄,效果與shell中的*
withnullglob
和dotglob
set相同,並使前面的只匹配正常文件。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 ... | ... -0
or-0 ... ::: *
如上所示):\ls | parallel 'echo -n {}" "; ls {}|wc -l'
(PS:你知道嗎
--tag
:parallel --tag 'ls {}|wc -l' ::: *
)