이미 질문하고 답변한 유사한 질문을 하고 있다는 것을 알고 있지만 정규식과 정규식 엔진이 충분히 다르기 때문에 필요한 답변을 추론할 수 없었습니다. 파이프로 구분되어 있지만 끝점 간에 크게 구분되지는 않는 하드웨어 자산 관리 로그가 있습니다. 로그는 다음과 같습니다.
|STATUS1|HOSTNAME1|IP1|MAC1|IS_WIRED1|STATUS2|HOSTNAME2|IP2|MAC2|IS_WIRED2|STATUS3|HOSTNAME3|IP3|MAC3|IS_WIRED3
내가 하고 싶은 것은 6일마다 |
다음과 같이 캐리지 리턴으로 바꾸는 것입니다.
|STATUS1|HOSTNAME1|IP1|MAC1|IS_WIRED1
|STATUS2|HOSTNAME2|IP2|MAC2|IS_WIRED2
|STATUS3|HOSTNAME3|IP3|MAC3|IS_WIRED3
내가 얻은 가장 가까운 것은 각 끝점을 선택하지만 powershell을 사용하여 이를 활용하는 방법을 잘 모르겠습니다.
[^\|]*\|[^\|]*\|[^\|]*\|[^\|]*\|[^\|]*\|[^\|]*
나는 PS의 교체 명령에 익숙하며 최종 결과는 다음과 같을 것이라고 상상합니다.
$hosts = $hosts -replace "<highspeed_low_drag_velcro_snap_regex_here>","\r\n"
미리 감사드립니다!
답변1
좋아요, 사실 이건 좀 까다롭습니다. 틀림없이 정규식은 작업에 가장 적합한 도구는 아니지만 그렇게 할 수 있습니다.
-replace "(?<=^((\|[^|]*){5})+)\|","`n|"
나는 당신에게 그것을 안내하려고 노력할 것입니다:
- 텍스트에 원하는 섹션이 있습니다.성냥그리고 원하는 섹션바꾸다. 전통적으로 정규식은 전체 검색 문자열을 대체하므로캡처 그룹대체 출력에 복제할 검색 문자열의 일부를 지정합니다. 또 다른 방법은둘러보기, 이것이 제가 여기서 한 일입니다. PowerShell(.NET)은 다음을 지원하는 몇 안 되는 정규식 언어 중 하나입니다.가변 길이 뒤돌아보기, 그래서 우리는 운이 좋았습니다.
- 섹션은
(?<=)
뒤돌아보기입니다. 이는 the=
와)
is 사이의 모든 것을 의미합니다.일치하지만교체됨. 그래서^((\|[^|]*){5})+
다음과 같이 사용됩니다.상태- 대체는 이 비트가 의도된 대체 이전의 텍스트와 일치하는 경우에만 발생합니다. - 섹션은 "줄의 시작 부분( )부터 5개의 s 세트를 일치시킨 다음 텍스트를 다음까지 일치시킵니다 "
^((\|[^|]*){5})*[^|]*
로 요약할 수 있습니다 .^
|
|
- 줄의 시작은
^
중요합니다. 그렇지 않으면 줄의 어느 곳에서나 일치할 수 있으며 이전에 몇 개의 가 왔는지 보장할 수 없습니다|
. - 정규식에서 특별한 의미를 갖기 때문에
|
이스케이프해야 합니다\|
. 문자 클래스( ) 내에서는 이스케이프할 필요가 없습니다[]
. [^|]*
"다음까지의 텍스트"를 의미합니다 . 더 기술적으로는 " 가능한 것|
보다 많은 문자 "를 의미합니다. 더 기술적으로는 " 문자 클래스를 가능한 한 많이 반복합니다. 여기서 해당 문자 클래스는 " 이외의 문자와 일치합니다 .|
[^|]
|
*
"가능한 한 많이 이전 문자를 0개 이상 반복함"을 의미합니다.- 따라서 다음까지 가능한 한 많은 문자가
(\|[^|]*)
일치하는 것을 의미합니다 . 이것은 일치합니다|
|
|text
{5}
이는 이전 토큰을 정확히 5번 반복한다는 의미입니다. 앞의 토큰을 5번 복사하여 붙여넣는 것과 정확히 같습니다. 그러면 이것이 일치할 것이다|text|text|text|text|text
((\|[^|]*){5})+
해당 전체 그룹을 한 번 이상 반복하는 것입니다. 따라서|text|text|text|text|text
, 등을 일치시킬 수 있습니다 . - 5의 배수로 우리가 대신을|text|text|text|text|text|text|text|text|text|text
사용하는 이유는 빈 그룹을 일치시키고 첫 번째 그룹을 바꾸고 싶지 않기 때문입니다 .+
*
|
- 그리고 그것은 전체 뒤를 돌아보게 만듭니다. 즉, 라인의 시작부터
|
정확히 5 초 뒤에 있는 a를 대체한다는 의미입니다.|
- 줄의 시작은
- 그 다음에는
\|
대체할 실제 텍스트로 a를 붙이고 일치하는 뒤돌아보기가 앞에옵니다. 귀하의 예를 들면
|STATUS1|HOSTNAME1|IP1|MAC1|IS_WIRED1|STATUS2|HOSTNAME2|IP2|MAC2|IS_WIRED2|STATUS3|HOSTNAME3|IP3|MAC3|IS_WIRED3
다음과 일치합니다.|STATUS1|HOSTNAME1|IP1|MAC1|IS_WIRED1**|**STATUS2|HOSTNAME2|IP2|MAC2|IS_WIRED2**|**STATUS3|HOSTNAME3|IP3|MAC3|IS_WIRED3
여기에서(아직 하지 않은 경우) 실제로 모든 항목을 교체하려고 한다는 것을 알 수 있습니다.5번째 |
첫 번째 빼기, 전부는 아님6번째. 그러나 Lookbehind 메소드는 "첫 번째 마이너스" 상황을 상당히 깔끔하게 처리합니다.
이제 대체 문자열입니다.
- 이것이 PowerShell이기 때문에 우리가 원할 때 PowerShell 이스케이프 문자가 이기 때문에
\n
실제로 원합니다 . 이는 대체 문자열에만 필요하다는 점에 유의하세요. 정규식 자체에서는 해당 리터럴 시퀀스를 정규식 엔진에 전달하는 데 계속 사용됩니다.`n
`
\n
- 그리고 모든 줄에 선행이 있으므로 새 줄 뒤에
|
새 줄을 추가해야 합니다 .|
이는 원래 줄이 a로 끝나지 않기 때문에 작동합니다.|
따라서 줄 끝에서 바꿀 것이 없으므로 추가 새 줄이나 후행으로 끝나지 않습니다|
.
보다 전통적인 캡처 그룹 방법을 선호하는 경우:
-replace "((?:[^|]+\|){4}[^|]+)\|","`$1`n|"
이것이 어떻게 작동하는지 파악하는 것은 독자의 연습 문제로 남겨집니다. ;) 팁: $1
역참조는 를 사용하여 이스케이프해야 합니다. `
그렇지 않으면 PowerShell이 이를 셸 변수로 해석하기 때문입니다.