如何递归移位``:`` 使用 `xargs` 或 `exec` 通过特定值

如何递归移位``:`` 使用 `xargs` 或 `exec` 通过特定值

我正在尝试使用or递归地将<user_id>:<group_id>按特定值移动。我在使用函数将输出传递给变量时遇到困难。我运行的是 Ubuntu 20.04。xargsexecfindstat

find . -type f,d | xargs chown $(($(stat --printf %u {})+1)):$(($(stat --printf %g {})+1)) {}

stat: cannot stat '{}': No such file or directory

stat: cannot stat '{}': No such file or directory

chown: cannot access '{}': No such file or directory

答案1

我会zsh在这里使用:

#! /bin/zsh -
# enable the stat builtin (which btw predates GNU stat by several years)
zmodload zsh/stat || exit

# enable chown (and other file manipulation builtin)
zmodload zsh/files || exit
ret=0

for f (./**/*(DN.,/) .) {
  stat -LH s $f && # store file attributes in the $s hash/associative array
    chown $((s[uid] + 1)):$((s[gid] + 1)) $f || ret=$?
}
exit $ret # report any error in stat()ing or chown()ing files

(其中Ddotfile 表示包含隐藏文件, nullglob 表示如果未找到常规文件或类似目录,N则不将其视为错误)。.,/-type f,d

如果在像 Ubuntu 20.04 这样的 GNU 系统上,您还可以执行以下操作:

find . -type f,d -printf '%p\0%U\0%G\0' | # print path, uid, gid as 3
                                          # nul-delimited records
  gawk -v RS='\0' -v ORS='\0' '{
    file = $0; getline uid; getline gid
    print (uid+1) ":" (gid+1); print file}' | # outputs a uid+1:gid+1
                                              # and path record for each file
  xargs -r0n2 chown # pass each pair of record to chown

但由于这涉及chown每个文件运行一个(在该zsh方法中,我们运行模块chown中的内置函数zsh/files),因此效率会低很多。

答案2

使用 GNU Parallel 时,它看起来像这样:

find . -type f,d |
  parallel 'chown $(($(stat --printf %u {})+1)):$(($(stat --printf %g {})+1)) {}'

相关内容