私はこのコマンドのさまざまな部分が何をしているのかをすでに知っています。
zgrep -v "org" /path/to/files/* | zgrep "FollowEvent" | zgrep -o 'login":"[^"]*"' | cut -d'"' -f3 | sort | uniq -c | sed '1i{
s/\s*\([0-9]*\)\s*\(.*\)/"\2": \1,/;$a}' > usernames_followevents.txt
少しずつ:
1)ファイル(検索)zgrep
に使用されます。grep
.json.gz
2)は、含まれていないzgrep -v "org" /path/to/files/*
ファイルをそれぞれ検索することを意味します。/path/to/files/*
"org"
3)|
パイプです。 「その時」を意味します。
4)zgrepで見つかった最初の結果から文字列を検索することを示しますzgrep "FollowEvent"
。"FollowEvent"
5)は|
「その時」を意味するパイプです。
6)空でない一致のzgrep -o 'login":"[^"]*"'
検索文字列login":"
と「login」という単語の後のすべてのテキストを表します。
7)| cut -d'"' -f3
は、「次に結果一致から3番目のフィールドを取得します」を意味します。この場合はユーザー名です。
8)| sort | uniq -c
は、「次にユーザー名を並べ替え、各ユーザー名の一意のインスタンス数を計算します」を意味します。
これまでのところ、
zgrep -v "org" /path/to/files/* | zgrep "FollowEvent" | zgrep -o 'login":"[^"]*"' | cut -d'"' -f3 | sort | uniq -c
文字列 "org"は含まれていませんが、 "FollowEvent"文字列は、/path/to/files/*に含まれるすべてのファイルのすべての項目ですべてのユーザー名を検索します(これは " "の後の3番目のフィールドのテキストです) 。 ") 次に、これらのユーザー名をソートし、各ユーザー名の発生回数を計算します。
私の問題はこの部分です。
sed '1i{ s/\s*\([0-9]*\)\s*\(.*\)/"\2": \1,/;$a}'
私はこの程度を知っています(または知っていると思います):
1)sed
テキスト操作を許可するフローエディタです。
2) はsed '1i{
「前の行に{挿入」を意味します。
3)要約すると、このコマンドは{"username":count of that username}
前述のようにすべてのファイルのすべてのユーザー名を返します。それからこれをusernames_followevents.txt
。
4)この部分は、"\2":
「ユーザー名と2番目のフィールド(?)を二重引用符で囲み、次を挿入します。」を意味します。
コマンドを操作したいのですが、sed
残りの詳細がわからない場合は変更を開始できません。
sed
命令の各部分が何をしているかを説明できる人はいますか?
答え1
sed コマンドを作成する現在の方法が正しくありません。次のスクリプトでなければなりません。
1i{
s/\s*\([0-9]*\)\s*\(.*\)/"\2": \1,/
$a}
または、次のように1行で作成します。
sed -e '1i{' -e 's/\s*\([0-9]*\)\s*\(.*\)/"\2": \1,/' -e '$a}'
文字通り、コマンドの後に入力したすべての内容i
とa
改行文字または式の終わりまで(-eを使用)、標準出力に直接印刷されます。
その機能を分析してみると次のようになります。
1i{
1
行アドレスです。 sedにいつコマンドを実行するかを指示します。最初の行の内容をパターン空間に読み込むとき(末尾の改行文字なし)、i
標準出力の別の行に「{」を挿入します。パターン空間は変更されず、「{」は追加されませんでした。
s
検索と置換コマンドは、sedで最も一般的なコマンドです。\s
スペースと一致します。\(regex\)
正規表現は数学と同様にグループ内でグループ化されますが、一致はグループ順序(\1〜\9)に従って数値レジスタにも格納されます。
出力はuniq -c
次のとおりです。
occurrences string
3 user
今、複雑な部分が出てきます。
\s*\([0-9]*\)\s*\(.*\)
まだ1号線にあります。パターン空間は空白の塊で、次に「3 user」です。これを一致させるには、空白を0回以上検索し、数字を複数回検索します。つまり、レジスタ \1 に格納された数字 (私の考えには * ではなく + でなければならない) を検索してから空白 (* 必要ではないと思う) を検索します。 )、すべての文字が複数回(やはり+が良い)レジスタ\ 2に格納されます。これで、発生項目は\ 1にあり、文字列/ユーザーは\ 2にあります。
"\2": \1,
行全体が一致し、フラグメントが保存されました。次に、一致する内容を引用符、ユーザー、引用符、コロン、スペース、項目、およびカンマで置き換えます。
$a}
$
行アドレスでもあります。現在の行が最後の行である場合(現在ではない)、このa
コマンドを呼び出して別の行の標準出力に「}」を追加します。
このコード処理ラインは、ジョブが完了した後にパターン空間が自動的に印刷され、次の2行目の内容が読み取られ、サイクル全体が繰り返されます。
出力例:
{
"user": 3,
}
インデントは間違っていますが、デフォルトではJSONファイル形式です。
それはすべてです。小説を書いてごめんなさい:)