特定のファイル形式内でパターン間の行数を見つける

特定のファイル形式内でパターン間の行数を見つける

notes.json各ディレクトリにファイルがあります。次のコマンドは、notes.json各ファイルの長さを計算し、各ファイルの行数に基づいてソートされた出力を返します。

find . -name notes.json | xargs wc -l | sort -nr

それは戻ってくる

789 ./D/notes.json
789 ./F/notes.json
574 ./A/notes.json
519 ./G/notes.json

今私は検索モード内部コンテンツの各ファイルに対してソートされた行数をnotes.json返したいと思います。notes.json

私は努力したfind . -name notes.json | xargs cat | jq '."text1[]"' | wc -l。ただし、text1[ ]All間の合計行数である1つの値のみを受け取りますnotes.json。もちろん、catすべてのファイルのパターンマッチングが一緒に出力されるからです。notes.json各ファイルの行の長さ(一致パターンから返されます)をソートして出力する方法はありますか?

答え1

  • ソートされていない出力:

何千ものjsonファイルを含む私のファイルツリーで、以下を試してください。

$ find . -type f -name "*[0-9].json" \
    -exec bash -c 'printf "%4d %s\n" $(jq ".bbx_basic[]" "$1" | wc -l) "$1"' bashscript {} ';'
[Example output in my tests]
 130 ./Images/Training_set/00000845.json
  13 ./Images/Training_set/00005869.json
  13 ./Images/Training_set/00000991.json
  26 ./Images/Training_set/00005631.json
1013 ./Images/Training_set/00001737.json
...
 410 ./Annot_txt/Coco_en_2017/instances_val2017.json
   0 ./Annot_txt/Coco_en_2017/instances_val2017.json

これにより、検索は通常のファイルに制限され、私のパターンで指定されたファイル名を見つけます*[0-9].json。あなたの場合は、次のコマンドを実行する必要があります。

 $ find . -type f -name "notes.json" \
     -exec bash -c 'printf "%6d %s\n" $(jq ".text1[]" "$1" | wc -l) "$1"' bashscript {} ';'
  • 種類出力:
    • outfile変更されたコマンドは、ソートして標準出力に送信するよりも多くの操作を実行したい場合に備えて、ソートされていない出力を中間一時ファイル(名前)に保存します。/tmp/必要に応じて、ディレクトリ内のファイルを見つけることができます。
    • 逆ソートは最初の(数値)フィールドで実行されるため、指定されたロケールに依存してはいけません。
    • find終了状態に関係なくバックグラウンド実行ジョブが終了すると、ソートが開始されます。

パスワード:

$ find . -type f -name "notes.json" \
    -exec bash -c 'printf "%6d %s\n" $(jq ".text1[]" "$1" | wc -l) "$1" 2>/dev/null >> outfile' bashscript {} ';'; sort -k1,1nr outfile

上記の内容は、次の方法で同時により強力で柔軟にすることができます。

$ find . -type f -name "notes.json" -exec sh -c '
    for file do
      printf "%6d %s\n" $(jq ".text1[]" "$file" 2>/dev/null | wc -l) "$file"
    done' sh {} + >> outfile; sort -k1,1nr outfile

結果は同じですが、@StéphaneChazelasの提案による改善は次のとおりです。

  • sh携帯性を高めるよりも使用することでbash
  • 結果をファイルごとに処理find ...-exec sh -c '...'()する代わりに、バッチ()で生成されるシェルの数を最小限に抑えます。+\;find
  • outputfind以前のようにファイルごとにリダイレクトするのではなく、出力全体をリダイレクトして開いているファイル記述子()の数を最小限に抑えます。

答え2

なぜ必要なのかという論理的な推論はありますか?改行文字が不要なので、1行に多数のレコードを書き込むことができます。むしろ相手の武器を間違って選んだと言いたいです。JSON。したがって、私は以下を使用することをお勧めします。PHPコマンドラインインタフェース、例えば。 JSON配列の項目数を計算します。デフォルトでは、現在のバージョンにはJSONファイル形式のドライバが付属しています。使用するPHP関数は次のとおりです。get_file_contents()json_decode()そしてsizeof()

答え3

申し訳ありませんが、このリクエストには1文を書くことはできません。次のスクリプトは問題を解決します。

#!/bin/bash
declare -a arr
arr=()
for i in $(find . -name notes.json)
do
  arr+=`(echo $i | xargs cat | jq '.text1[]'  | wc -l); echo $i; echo "\n"`
done
echo -e $arr | sort -nr > out.txt

関連情報