mypasswd
というファイルから、4番目のフィールド値が1001または1003である行を印刷しようとしています。正規表現でのみgrepまたはegrepを使用できます。これがファイルです:
daemon:x:2:2:Daemon 1001:/sbin:/bin/bash
ftp:x:40:49:FTP export account:/srv/ftp:/bin/bash
daemonuser:x:50:59:nouser/bin/false:/home/nouser:/bin/bash
gdm:x:106:111:Gnome Display Mgr daemon:/var/lib/gdm:/bin/false
haldaemon:x:101:102:User for haldaemon:/var/run/hald:/bin/false
lp:x:4:7:Printing daemon:/var/spool/lpd:/bin/bash
mail:x:8:12:Mailer daemon:/var/spool/clientmqueue:/bin/false
root:x:0:0:root:/root:/bin/bash
sshd:x:71:65:SSH daemon:/var/lib/sshd:/bin/false
olivert:x:1001:1005:Tom Oliver:/home/olivert:/bin/csh
smiths:x:1049:1000:Sue Williams:/export/home/smiths:/bin/csh
northj:x:1003:1003:Jim jones-North:/home/northj:/bin/csh
denniss:x:1005:1003:Sue Dennis:/home/denniss:/bin/bash
smitha:x:1050:1001:Amy Smith:/export/home/smitha:/bin/bash
jonesc:x:1053:1001:Cathy Jones:/export/home/jonesc:/bin/ksh
smithd:x:1055:1001:Dan Smith Jr:/export/home/smithd:/bin/csh
したがって、出力は
northj:x:1003:1003:Jim jones-North:/home/northj:/bin/csh
denniss:x:1005:1003:Sue Dennis:/home/denniss:/bin/bash
smitha:x:1050:1001:Amy Smith:/export/home/smitha:/bin/bash
jonesc:x:1053:1001:Cathy Jones:/export/home/jonesc:/bin/ksh
smithd:x:1055:1001:Dan Smith Jr:/export/home/smithd:/bin/csh
簡単に実行できますegrep '1001|1003' mypasswd
ですが、「デーモン」(5番目のフィールドには「1001」が含まれています)と「オリバート」(3番目のフィールドは「1001」)も与えられます。 egrep/grep正規表現を使用して、これら2つの数値に一致する4番目のフィールド値(3つのコロンの後にある値)が必要です。これで長期的に私を助けてくれるので、どんな答えも大歓迎です。
私の意見では、awk
のようなツールを使用するほうがより直接的です。
例えば:
awk -F: '$4 == 1001 || $4 == 1003' mypasswd
... awkに次のように伝えます。
-F:
を使用して、入力行をコロンに基づいてフィールドに分割しますAwkは少し習得できます。それについて理解する主要なことの1つは、「パターン」と「アクション」のペアのステートメントを使用することです。 「パターン」セクションは、どの「アクション」ステートメントが実行されるかを決定します。
上記のawkを書き換えて、より明確にすることができます。そうすることで、必要なもの(5番目のフィールドなど)を明示的に出力できます。
awk -F: '$4 == 1001 || $4 == 1003 { print $5 }'
...または、空の「パターン」セクションを作成するには、つまり、「アクション」をevery行に対して実行し、アクションパターン内で値をテストします。
awk -F: '{ if ($4 == 1001 || $4 == 1003) print $5 }'
grep
を強制的に実行するには、次のようにします。
grep -E '^([^:]*:){3}(1001|1003):' mypasswd | cut -d: -f5
行の最初から、「何でもないコロンは何回でも、その後はコロン」というグループを探して、3回続けて1001または1003を探し、次にコロン;一致する行全体を出力しますが、それをcut
に渡して5番目のフィールドだけを出力します。
sed
でこれを行うかもしれません
sed -n '/^.*:.*:.*:\(1001\|1003\):/p' mypasswd
-n
は行を抑制し、最後のp
は一致する行を出力します。
grep
でそれを行うこともできます
grep '^.*:.*:.*:1002\|1003:.*:.*:' mypasswd
@JeffSchallerが言うように、awk
はジョブのツールであり、OPはregex
を必要とするため、2つを組み合わせることができます
awk -F: '$4 ~ /^100[13]$/' mypasswd
そして、それはgrep
バージョンに小さなゴルフパットを許可します
grep -E "^(.*:){3}100[13]:" mypasswd
必須のPerlソリューション:
フィールドを数値として解釈します。
Perl -F: -ane 'print if $F[3] == 1001 || $F[3] == 1003' mypasswd
または正規表現を使用する
Perl -F: -ane 'print if $F[3] =~ /^(1001|1003)$/' mypasswd
またはやや短い正規表現:
Perl -F: -ane 'print if $F[3] =~ /^100[13]$/' mypasswd
または、算術を使っていくつかのトリックを実行します(これは少しこっそりです):
Perl -F: -ane 'print if abs($F[3] - 1002) == 1' mypasswd
オプションは次のとおりです:-a
=配列に自動分割@F
(インデックス作成はzeroで開始)、-F:
= :
をフィールド区切り文字として使用、-ne
各行に対してここでスクリプトを実行します
行の始め/終わりへのアンカー(^
および$
)は、11001
または10010
のような数値が一致しないようにするために必要です。
"egrep/grep正規表現を使用してこれらの2つの数値と一致する4番目のフィールド値(3つのコロンの後にある値)が必要です"
4番目のフィールドだけが必要な場合は、cut
とgrep
を次のように使用します。
$ cat mypasswd | cut -d: -f4 | grep -E '^(1001|1003)$'
1001
1003
grep
パターンは、行の最初と最後にアンカーする必要があります。それ以外の場合は、10010
のような数字と一致する可能性があります。これを行う別の方法は、grep -x -E '1001|1003'
です。
これを機能させるには、行全体を印刷する必要がありますが、4番目のフィールド値を強調表示する必要があります。
唯一のgrep
は、「フィールド値」を「強調表示」して、色を付けることです。そうしたい場合は、拡張 StéphaneChazelasの調整 オン ilkkachuの調整 オン StrongBadの回答 を拡張できます。
_grep -E '^[^:]*:[^:]*:[^:]*:(1001|1003):[^:]*:[^:]*:' mypasswd
_
(これがGNU grep
であると仮定すると、これはLinuxでは通常のことです)PCREマジックを追加します。
_grep --color -P '^[^:]*:[^:]*:[^:]*:\K(1001|1003)(?=:[^:]*:[^:]*:)' mypasswd
_
_\K
_は、これまでの正規表現で一致したテキストが、正規表現の一致から除外されます。 (?=regex)
は(正の)先読みです。 _1001
_または_1003
_は、その後にコロンと3つのフィールドが続く場合にのみ一致する必要があることを示しています。
問題の入力ファイルが与えられると、上記のコマンドは次の出力を生成します。
northj:x:1003:1003:Jim jones-North:/ home/northj:/ bin/csh denniss:x:1005:1003:Sue Dennis:/ home/denniss:/ bin/bash smitha:x:1050:1001:Amy Smith:/ export/home/smitha:/ bin/bash jonesc:x:1053:1001:キャシー・ジョーンズ:/ export/home/jonesc:/ bin/ksh smithd:x:1055:1001:Dan Smith Jr:/ export/home/smithd:/ bin/csh
太字の斜体のテキストに色を付けています。
次に、passwdファイルで機能する別のバージョンを示します。
grep -E --color=auto ':[[:alnum:]]+:[[:digit:]]+:(1001|1003):' mypasswd
説明:
grep -E
は拡張正規表現を有効にするため、(1001|1003)
でOR構文を使用できます。 (-E
を追加したことによるもう1つの結果は、+
およびその他の特殊文字をエスケープする必要がないことです。)--color=auto
は完全にオプションです。一致した文字列に色を付けるだけです。':[[:alnum:]]+:[[:digit:]]+:(1001|1003):'
は、コロン、1つ以上の英数字、コロン、1つ以上の数字、コロン、1001または1003の順に続く文字列に一致します。結腸。 (2番目のフィールドがalways "x"であるコンテキストでは、[[:graph:]]+
をx
に置き換えることができます。)質問のサンプルデータの場合、これは次の出力を提供します(カラーリングは削除されています)。
northj:x:1003:1003:Jim jones-North:/home/northj:/bin/csh
denniss:x:1005:1003:Sue Dennis:/home/denniss:/bin/bash
smitha:x:1050:1001:Amy Smith:/export/home/smitha:/bin/bash
jonesc:x:1053:1001:Cathy Jones:/export/home/jonesc:/bin/ksh
smithd:x:1055:1001:Dan Smith Jr:/export/home/smithd:/bin/csh
3回ホップして、3番目の結腸に止まる。次に、中断したところから検索を実行し、コロンを押す前に1001または1003を探します。検索が成功した場合は、行を印刷します。
$ Perl -ne ' /:/g;//g;//g;/\G100[13]:/&&print' file
Gnu sed
$ sed -e 'h;s/:/\n/4;/:100[13]\n/!d;g' file