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()
キーワードとともに呼び出されます。各結果ファイル名は一時変数に割り当てられ、ブロック内で繰り返されます。for
test => / \.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
上記のファイル名のテキスト部分を分離することは、match
Rakuの新しいプレビュー/振り返りイディオムに依存します。<(
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]