/ etc / passwdファイルを処理して、ホームフォルダーが/ homeにあるすべてのユーザーをリストします。


10

次のような/ etc / passwdファイルの例があります。

tom:x:1000:1000:Work:/home/tom:/bin/bash
george:x:1000:1000:Work:/home/george:/bin/bash
bla:x:1000:1000:Work:/home/bla:/bin/bash
boo:x:1000:1000:Work:/home/boo:/bin/bash
bee:x:1000:1000:Work:/root/list:/bin/bash

にホームフォルダーがあるすべてのユーザーを一覧表示しようとしています/home/

私が書いた

cat ~/Desktop/e.txt |awk -F ":" '{if ($6 ~/^/home/) print $1;}'

ここで、e.txtはここにコピーしたテキストです。

エスケープ文字であるバックスラッシュに問題があることを理解していますが、コマンドの1行にリストできるようにするにはどうすれば修正できますか?


11
(!の間でちょうど1秒で来ている)の回答以外にも一般的なアドバイス:それは理にかなってことはほとんどないcatとのパイプのようなツールにawksed、彼らは、引数としてファイル名を与えることができるように、など。
フィリポス

1
cat e.txt | grepホーム| cut -d ":" -f 1
Arpit Agarwal 2017年

3
すべてのユーザーのUIDが1000であるため、少し注意が必要かもしれません。
StrongBad 2017年

1
@ArpitAgarwal grep home e.txt | cut -d ":" -f 1。UUOCアワードおめでとうございます。ただし、これは良い解決策ではありません。デーモンにちなんで名付けられた別のユーザーの下で実行されるサービス「homebackups」がある場合はどうなりますか?それは誤検知です。
NieDzejkob 2017年

2
@Philippos re「キャットアンドパイプでツールにパイプすることはほとんど意味がありません[ファイル名を引数として指定できます]- cat > tool左から右へのフローを維持することで明瞭性を向上できるため、通常はそのようなコマンドラインのバリアントを使用しますパイプチェーンの入出力処理の。それはあるが、ほとんど常に最小限ので、あまり効率的。また、インタラクティブに実行する場合に関連性があり便利な進行状況バーを追加します(インストールされcatているpv場合は置き換えてください)。
David Spillett

回答:


11

次のようにスラッシュをエスケープできます。

awk -F':' '$6~/^\/home\//{ print $1 }' ~/Desktop/e.txt

もう1つのトリックは、複雑なフィールドセパレータを使用することです。

awk -F'[:/]' '$7=="home"{ print $1 }' ~/Desktop/e.txt
  • -F'[:/]'- :/フィールドセパレーターの両方を扱います

2
コメントフィールド(ホームディレクトリの直前)にはスラッシュを含めることができると思います。

12

/エスケープを回避するために、正規表現の代わりに引用符を使用できます/

awk -F: '$6 ~ "^/home/" {print $1}' ~/Desktop/e.txt

を使用するとawk{if (foo) ... }多くの場合、単にに簡略化できfoo {...}ます。


8

ユーザーアカウント情報はLDAPなどで指定された複数の場所に格納される可能性があるため、実際にe.txtはであると想定して、ファイルを解析/etc/passwdするgetent passwd代わりに実際に使用する必要があり/etc/nsswitch.confます。

getent passwd | awk -F ':' '$6 ~ "^/home"'

print条件が真の場合、ステートメントが暗黙に含まれることに注意してください。ただし、行全体が出力されます。これはユーザー名のみを出力します:

getent passwd | awk -F ':' '$6 ~ "^/home" {print $1}'

4

awkが嫌いな人のための代替:

grep -E '^([^:]*:){5}/home/' ~/Desktop/e.txt | cut -d: -f1

説明:

  • grep -E いくつかの拡張正規表現機能の使用を可能にします
  • ([^:]*:)は、次の「:」区切り文字を含む1つの列に一致します
  • ^([^:]*:){5} 各行の最初の5列に一致
  • ^([^:]*:){5}/home/ 6番目の列が「/ home /」で始まるすべての行に一致します
  • cut -d: -f1:列セパレータとして使用して、入力の最初の列のみを選択します

3

indexような固定文字列マッチングにgrep -F使用し、戻り値を使用して文字列の先頭に一致することを確認することもできます

$ awk -F: 'index($6,"/home/")==1{print $1}' ip.txt
tom
george
bla
boo

または正規表現が必要な場合は、環境変数として渡します

$ r='^/home/' awk -F: '$6 ~ ENVIRON["r"]{print $1}' ip.txt
tom
george
bla
boo

3

多様性のためだけに

$ perl -F: -lane 'print $F[0] if m(/home/)' e.txt
tom
george
bla
boo

説明

-F:     use ":" as field separator  
-lane
    l   add newline line-ending to every print statement
    a   auto-split input lines into @F array
    n   apply expression line by line to named file (or STDIN)
    e   evaluate perl commands given on command line

print $F[0]   print (only) the first field of each line
if m(/home/)  but only if the line contains the text /home/

バリエーションどこ好き嫌いになりたい場合は/home/発見されました

perl -F: -lane 'print $F[0] if $F[5] =~ m(^/home/)' e.txt
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.