如何根据文件夹名称更改所有文件夹和文件的权限?

发布于 2025-01-10 03:23:29 字数 287 浏览 0 评论 0原文

例如,我们有一个名为 555 或 700 或 777 的文件夹...我们如何获取文件名并根据文件夹名称更改具有权限的所有子文件夹和文件? 因此,如果我们将其应用于文件夹 555,则当前文件夹及其内部的所有内容都将具有 555 的权限 我已经尝试过

find . -name "[0-9][0-9][0-9]" -type d | xargs chmod -Rv [0-9][0-9][0-9]

,但它只需要第一个文件夹名称并将其应用于我希望它单独处理每个文件夹名称(以权限命名)的所有内容 谢谢。

For exemple we have folders named with permission numbers 555 or 700 or 777... how can we take the file name and change all the subfolders and files with permissions based on the folder name ?
so if we apply it on the folder 555 the current folder and everything inside will have permission as 555
i've tried

find . -name "[0-9][0-9][0-9]" -type d | xargs chmod -Rv [0-9][0-9][0-9]

but it only takes the first folder name and apply it on everything it i want it to treat each folder name ( named withe permission) seperately
thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝色星空 2025-01-17 03:23:29

不确定是否理解问题。

需要示例输入和示例输出才能理解。

建议以下解决方案:

 dir_name="555"; chmod -R "$dir_name" $(find . -path "*$dir_name*")

解释

dir_name="555";:分配一个变量dir_name,该变量保存目录名称555chmod权限值555

< code>$(find . -path "*$dir_name*"):列出当前目录下路径中某处具有 555 的所有文件。

chmod -R "$dir_name":使用 dir_name 值的 Chmod 命令 555

Not sure understand the question.

Need sample input and sample output to understand.

Suggesting following solution:

 dir_name="555"; chmod -R "$dir_name" $(find . -path "*$dir_name*")

Explanation

dir_name="555";: Assign a variable dir_name that holds the directory name 555 and the chmod permission value 555

$(find . -path "*$dir_name*"): List all files under current directory having 555 somewhere in their path.

chmod -R "$dir_name": Chmod command using the value of dir_name 555

魔法唧唧 2025-01-17 03:23:29

我会用这样的东西。

find . -type d -name '???' -printf '%f\n' | xargs -I'{}' chmod -R  '{}' '{}'
  • -type d -- 仅查找目录。
  • -name ??? -- 这将覆盖名为 555、700、777 等的目录
  • printf '%f\n' -- 仅打印目录的名称。

为了真正安全起见,我会添加另一个选项 (-maxdepth):

find . -maxdepth 1 -type d -name '???' -printf '%f\n' | xargs -I'{}' chmod -R  '{}' '{}'
  • maxdepth 1 -- 不要对子文件夹进行任何搜索。

I'd use something like this.

find . -type d -name '???' -printf '%f\n' | xargs -I'{}' chmod -R  '{}' '{}'
  • -type d -- find only directories.
  • -name ??? -- this will cover directories named 555, 700, 777, etc
  • printf '%f\n' -- print only directory's name.

To be really safe, I would add another option (-maxdepth):

find . -maxdepth 1 -type d -name '???' -printf '%f\n' | xargs -I'{}' chmod -R  '{}' '{}'
  • maxdepth 1 -- Don't do any search on subfolders.
热鲨 2025-01-17 03:23:29

我尝试过查找。 -名称“[0-9][0-9][0-9]”-type d | xargs chmod -Rv [0-9][0-9][0-9] 但它只需要第一个文件夹名称并将其应用于我希望它单独处理每个文件夹名称(以权限命名)的所有内容

您的尝试是有几个方面是错误的,其中包括:

  1. [0-9][0-9][0-9] 模式匹配包含非八进制数字字符的名称。

  2. shell 解析命令时将扩展 [0-9][0-9][0-9] 模式。如果扩展成功,则第一个匹配的名称将给出要应用的模式。如果扩展成功,那么(默认情况下)模式本身将被传递到chmod,后者会将其视为无效模式而拒绝。

  3. 默认情况下,xargs 命令将采用尽可能多的输入来形成一个 命令的参数。因此,在您的示例命令中,如果 find 标识文件夹 700555755400< /code> 那么 xargs 最终将执行如下内容:

    chmod -Rv <... [0-9][0-9][0-9] ... 的扩展 ...> 700 555 755 400
    

    即使模式扩展为空(这可能在稍微不同的情况下发生),您也会得到与之前类似的结果:第一个目录名称将提供模式,而所有其他目录名称将更新为该模式。

此变体应该可以满足您的要求:

find . -name "[0-7][0-7][0-7]" -type d |
  sed 's,^.*/\([^/]*\)$,\1\n\0,' |
  xargs -r -l2 chmod -Rv

sed 命令获取由 find 发出的每个路径,提取基本名称,并将其放在单独的前一行上。例如,如果 find 发出的其中一行是 ,

./subdir/755

则 sed 会将其更改为

755
./subdir/755

.即要应用的模式和要应用的目录。

然后 xargs 的 -l2 选项告诉它在形成每个 chmod 命令时使用(最多)两个输入行,所以你最终会得到具有以下形式的一系列命令

chmod -Rv 755 ./subdir/755

xargs-r 选项是一个很好的功能,它告诉它在没有从标准输入读取任何行的情况下避免执行任何命令。

附录:更详细的 sed 表达式

[注意:我稍微简化了本答案原始版本中给出的 sed 命令。]

sed > command ...

  sed 's,^.*/\([^/]*\)$,\1\n\0,'

...根据给定的表达式处理每个输入行,这是一个带有逗号()分隔符的替代命令。

  • 目标模式为 ^\(.*/\)\([^/]*\)$。这匹配
    • 从行首开始的序列 (^),
    • 匹配任意数量的任意字符.*,
    • 后跟斜杠 (/) 字符,
    • 后跟除斜杠之外的任意数量的任意字符 ([^/]*)
    • 运行到行尾 ($)。
  • 最后一个斜线之后的部分被捕获为一个组。
  • 替换文本是
    • 第一个(唯一的)捕获组 (\1) 的内容,后跟
    • 换行符 (\n),后跟
    • 整个匹配项 (\0),这将是原始行,因为匹配项固定在该行的开头和结尾。

sed 将根据目标模式匹配每个输入行。任何包含至少一个斜杠的行都将匹配,并且给定 find 命令发出的每一行都将满足该条件。整个匹配(将是整行)将被给定的替换所替换,由两行组成 - 一行包含最后一个斜杠后面的原始行的尾部,另一行包含整个原始行。

i've tried find . -name "[0-9][0-9][0-9]" -type d | xargs chmod -Rv [0-9][0-9][0-9] but it only takes the first folder name and apply it on everything it i want it to treat each folder name ( named withe permission) seperately

Your attempt is wrong in several ways, among them:

  1. The [0-9][0-9][0-9] pattern matches names that include characters that are not octal digits.

  2. The [0-9][0-9][0-9] pattern will be expanded by the shell when it parses the command. If the expansion is successful, then the first matching name will give the mode to apply. If the expansion is not successful then (by default) the pattern itself will be passed through to chmod, which will reject it as an invalid mode.

  3. By default, the xargs command will take as many inputs as it can to form arguments to one command. So in your example command, if find identifies folders 700, 555, 755, and 400 then the xargs will end up executing something like this:

    chmod -Rv <... expansion of [0-9][0-9][0-9] ...> 700 555 755 400
    

    Even in the event that the pattern expanded to nothing (which could happen under slightly different circumstances) you have a result similar to before: the first directory name would provide the mode, and all the others would be updated to that mode.

This variation should do what you want:

find . -name "[0-7][0-7][0-7]" -type d |
  sed 's,^.*/\([^/]*\)$,\1\n\0,' |
  xargs -r -l2 chmod -Rv

The sed command takes each path emitted by find, extracts the base name, and puts that on a separate, preceding line. For example, if one of the lines find emits is

./subdir/755

then sed will change that to

755
./subdir/755

. That is, the mode to apply and the directory to which to apply it.

Then the -l2 option to xargs tells it to use (at most) two input lines in forming each chmod command, so you will end up with a series of commands of the form

chmod -Rv 755 ./subdir/755

The -r option to xargs is a nicety that tells it to avoid executing any commands at all if no lines are read from the standard input.

Addendum: the sed expression in more detail

[Note: I have slightly simplified the sed command given in the original version of this answer.]

The sed command ...

  sed 's,^.*/\([^/]*\)$,\1\n\0,'

... processes each input line according to the given expression, a substitute command with comma (,) delimters.

  • The target pattern is ^\(.*/\)\([^/]*\)$. This matches
    • a sequence starting at the beginning of the line (^),
    • matching any number of any character .*,
    • followed by a slash (/) character,
    • followed by any number of any character other than slash ([^/]*)
    • running to the end of the line ($).
  • The part after the last slash is captured as a group.
  • the replacement text is
    • the contents of the first (only) capture group (\1), followed by
    • a newline (\n), followed by
    • the whole match (\0), which will be the original line because the match is anchored to both the beginning and end of the line.

sed will match each input line against the target pattern. Any line containing at least one slash will match, and every line emitted by the given find command will satisfy that criterion. The whole match (which will be the whole line) will be replaced by the given replacement, consisting of two lines -- one containing the tail of the original line following the last slash, and the other containing the whole original line.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文