如何使用 awk 输出动态更改目录所有者?

如何使用 awk 输出动态更改目录所有者?

我想做的事 :

  • 获取用户及其主目录列表/etc/passwd
  • 使用用户名和家庭地址作为参数,并将这些目录的所有权更改给该用户。

电流输出:

修剪后的输出: cat /etc/passwd

##
# User Database
# 
# Note that this file is consulted directly only when the system is running
# in single-user mode.  At other times this information is provided by
# Open Directory.
#
# See the opendirectoryd(8) man page for additional information about
# Open Directory.
##
nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false
_uucp:*:4:4:Unix to Unix Copy Protocol:/var/spool/uucp:/usr/sbin/uucico
_taskgated:*:13:13:Task Gate Daemon:/var/empty:/usr/bin/false
_networkd:*:24:24:Network Services:/var/networkd:/usr/bin/false

修剪后的输出:cat /etc/passwd | grep "^[#;]" -v

nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false
_uucp:*:4:4:Unix to Unix Copy Protocol:/var/spool/uucp:/usr/sbin/uucico
_taskgated:*:13:13:Task Gate Daemon:/var/empty:/usr/bin/false
_networkd:*:24:24:Network Services:/var/networkd:/usr/bin/false
_installassistant:*:25:25:Install Assistant:/var/empty:/usr/bin/false

现在我必须删除开头的“_”,所以我使用了以下命令:

修剪后的输出:cat /etc/passwd | grep "^[#;]" -v | sed s/"_"//

nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false
uucp:*:4:4:Unix to Unix Copy Protocol:/var/spool/uucp:/usr/sbin/uucico
taskgated:*:13:13:Task Gate Daemon:/var/empty:/usr/bin/false
networkd:*:24:24:Network Services:/var/networkd:/usr/bin/false

最后我使用命令取出用户名和目录awk

cat /etc/passwd | grep "^[#;]" -v | sed s/"_"// | awk -F\: '{print $1" "$6}' (输出已修剪)

nobody /var/empty
root /var/root
daemon /var/root
uucp /var/spool/uucp
taskgated /var/empty
networkd /var/networkd
installassistant /var/empty
lp /var/spool/cups
postfix /var/spool/postfix
scsd /var/empty
ces /var/empty
appstore /var/db/appstore

这就是我想要进一步做的事情!

采取第一的参数并分配所有权第二对此的论证。我应该如何进行?

答案1

最后一个文件可以在 bash 中按如下方式处理:

cat YOURFILE | \
while read CMD; do 
   field1=${CMD% *};    # take first field
   field2=${CMD#* };    # take second field
   echo do $field1 with $field2;  # do something with it
done

因此,您必须用适当的 chown 命令替换 echo 才能使其正常工作。取自在 bash 脚本中逐行读取

答案2

我不确定您是否打算删除_这可能会导致的chown: _user not found问题chown

尝试

awk -F: '/^#/ { next } {printf "chown %s \"%s\"\n",$1,$6} ' my_etc_passwd

在哪里

  • -F:告诉 awk 用作:分隔符
  • /^#/ { next }跳过以以下开头的行#
  • 同样添加到以(如果需要)/^_/ { next }开头的跳过行_
  • 下一个模式/动作打印 chown 命令。

如果结果看起来不错,只需通过管道传输到bash

答案3

使用 awk 时,不需要一堆其他命令和管道。正确的写法:

cat /etc/passwd | grep "^[#;]" -v | sed s/"_"// | awk -F\: '{print $1" "$6}'

是:

awk -F':' '!/^[#;]/{sub(/_/,""); print $1, $6}' /etc/passwd

然后在 shell 中使用该输出(稍微修改 awk 命令以生成:- 分隔的输出,因为它具有- 分隔的输入,因此输入字段值中:必须没有s)::

while IFS=':' read -r user dir; do
    echo chown -- "$user" "$dir"
done < <(awk 'BEGIN{FS=OFS=":"} !/^[#;]/{sub(/_/,""); print $1, $6}' /etc/passwd)

或者如果您愿意:

awk 'BEGIN{FS=":"; OFS=ORS} !/^[#;]/{sub(/_/,""); print $1, $6}' /etc/passwd |
xargs -n 2 bash -c 'echo chown "$1" "$2"' bash

echo当您完成测试并想要实际执行时删除chown

答案4

使用 @Archemar 的答案,我使用了以下对我有用的代码!感谢您指出删除 _ 会出现错误。

awk -F\: '/^#/{next}''{system("chown " $1" " $6)}' /etc/passwd

相关内容