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를 사용합니다. 위의 코드는 Raku dir()
및 grep()
루틴에 의존하므로 기존 쉘 기반 파일 글로빙이 존재하지 않거나 제한되는 플랫폼에서 유용할 수 있습니다(SO 토론 참조).여기).
간단히 말해서, raku는 -e 옵션으로 호출됩니다. 이 옵션은 Raku의 컴파일러(Rakudo)에게 주어진 단일 라이너를 컴파일하고 실행하도록 지시합니다. 이 메소드는 Raku에게 필터에서 얻은 파일 이름 값을 반복하도록 지시하는 dir()
키워드와 함께 호출됩니다 . 각 결과 파일 이름은 임시 변수에 할당되고 블록 내에서 반복됩니다.for
test => / \.config $/
$fh
블록 내부에 있으면(오른쪽에서 왼쪽으로 읽음)
$fh.lines.grep(/^Name/)
각 파일 핸들을 한 줄씩 분석하여 "Name"이라는 텍스트로 시작하는 줄이 있는지 확인합니다. 발견되면 Raku는 자동으로 라인을$_
테마 변수에 할당한 다음 공백/등호로 분할하고.[1]
두 번째 요소(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]