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

したがって、正しく機能するには、echoを適切なchownコマンドに置き換える必要があります。からインポートBashスクリプトから1行ずつ読み込む

答え2

問題を_引き起こす可能性があるこのアイテムを削除したいかどうかはわかりません。chown: _user not foundchown

努力する

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

その後、シェルはその出力を使用します。:--delimited入力があるため、awkコマンドを少し変更して--delimited出力を生成するため、:入力フィールドの値に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

関連情報