ファイル名の特定部分とその内容のリスト

ファイル名の特定部分とその内容のリスト

BusyBoxがインストールされているLinuxシステムがあり、というディレクトリがあります/data/var/lib/connman。このディレクトリには、興味のないいくつかのディレクトリが含まれています。ただし、wifi_<HASH1>_<HASH2>_managed_psk.config" "などのファイル名パターンを持つ多くの.configファイルが含まれています。私の例のファイル名には、 <HASH1>_<HASH2>英数字の興味深いハッシュ部分が含まれています。完全なファイル名の例は次のとおりです。

  • "wifi_ff001122334_567890123456_management_psk.config"
  • "wifi_778899ad_112233445566_management_none.config"

次に、各ファイルはテキストファイルで、関心のある行が含まれている場合は次のようになります。

Name = <SSID>

興味深いことに<SSID>

この行の実際の例は次のとおりです。

Name = MySSID
Name = r23$f"§F §"fsdfSdf

これで、ファイル名からすべてのハッシュとその値を取得したいと思います。<SSID>、このように:

<HASH> : <SSID>

これが私が望む結果です:

MySSID : 01abcd89
MyOtherSSID : ff001122334455,
r23öf"§F§"fsdfSdf : 7876543ad

したがって、ファイル名からハッシュ部分を取得し、「Name =」の後のファイルの内容も確認する必要があります。

grepとawkの組み合わせを試しましたが、目的の結果が得られませんでした。

これを達成するためにどのコマンドを使用できますか?

答え1

使用幸せ(以前のPerl_6)

~$ raku -e 'for dir(test => / \.config $/ ) -> $fh {
                put join " : ",
                    $_.split(/ \s* \= \s* /)[1],
                    $fh.match(/ <?after wifi_ > .*? <?before _managed > /)
                for $fh.lines.grep(/^Name/)
             };'

このソリューションは、Perl プログラミング言語スイートに属する Raku を使用します。上記のコードはRakudir()grep()ルーチンに依存しているため、既存のシェルベースのファイルグロービングが存在しないか制限されているプラ​​ットフォームで役立ちます(SO議論を参照)。ここ)。

簡単に言えば、rakuは-eオプションで呼び出されます。このオプションは、Rakuのコンパイラ(Rakudo)に、指定された単一のライナーをコンパイルして実行するように指示します。このメソッドは、Rakuにフィルタから取得したファイル名の値を繰り返すように指示するdir()キーワードとともに呼び出されます。各結果ファイル名は一時変数に割り当てられ、ブロック内で繰り返されます。fortest => / \.config $/$fh

  • ブロック内にある場合(右から左に読み取る)、$fh.lines.grep(/^Name/)各ファイルハンドルを1行ずつ分析して、「Name」というテキストで始まる行があることを確認します。見つかった場合、Rakuは自動的に行を$_テーマ変数に割り当て、空白/等号に分割し、.[1]2番目の要素(SSID値)を分離します。

  • ファイル名も最終形式に調整され、$fh「wifi_」テキストの後と「_management」テキストの前にある.*?0個以上の文字を区切ります。<?after wifi_ ><?before _managed >

  • 結果の出力は要求された空白/コロンで編集されput、ファイル名部分で始まり、その後にSSID値が続きます。join:

入力例(パスワード):

~$ ls *.config
wifi_778899ad_112233445566_managed_none.config      wifi_ff001122334_567890123456_managed_psk.config

~$ cat wifi_778899ad_112233445566_managed_none.config
Name : SSIDabcd
junk
Name : SSIDefgh

~$ cat wifi_ff001122334_567890123456_managed_psk.config
Name : SSID1234
junk
Name : SSID5678

出力例:

SSIDabcd : 778899ad_112233445566
SSIDefgh : 778899ad_112233445566
SSID1234 : ff001122334_567890123456
SSID5678 : ff001122334_567890123456

上記のファイル名のテキスト部分を分離することは、matchRakuの新しいプレビュー/振り返りイディオムに依存します。<(Rakuの)>「キャプチャマーカー」を使用するには、タスクをmatch次のように変更できます。

$fh.match(/ wifi_ <( .*? )> _managed /)

https://docs.raku.org/routine/dir
https://docs.raku.org/routine/grep
https://raku.org

答え2

システムがbusyboxを使用しているので、Perlのようなものはないと思います。 busyboxは非常に強力なawk実装を備えているので、次のことができるはずです。

find . -name '*_*_*_*.config' -type f -exec awk '
  match($0, /^[[:blank:]]*Name[[:blank:]]*=[[:blank:]]*[^[:blank:]]/) {
    ssid = substr($0, RLENGTH)
    sub(/[[:blank:]]+$/, "", ssid)
    base = FILENAME
    sub(".*/", "", base)
    if (match(base, "_[[:xdigit:]]+_[[:xdigit:]]+_"))
      print ssid, substr(base, RSTART+1, RLENGTH-2)
    nextfile
  }' {} +

ビジーボックスがサポートなしで構築されている場合は置き換えることfind -exec {} +ができますが、+これは';'効率を低下させるだけです。

POSIX文字クラスをサポートせずにビルドされた場合と置き換えることawkができます。[[:blank:]][ \t][[:xdigit:]][0-9a-fA-F]

関連情報