파일 이름의 특정 부분과 해당 내용 나열

파일 이름의 특정 부분과 해당 내용 나열

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()키워드와 함께 호출됩니다 . 각 결과 파일 이름은 임시 변수에 할당되고 블록 내에서 반복됩니다.fortest => / \.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

위의 파일 이름 텍스트 부분을 분리하는 것은 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]

관련 정보