내 스크립트에서 3개의 숫자 뒤에 ","를 추가하는 코드 조각을 발견했습니다. 이 코드는 숫자 데이터만 고려합니다.
아래는 코드입니다.
sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' number.txt
번호.txt
1234
12345
123456
산출
1,234
12,345
123,456
1234,567
코드 흐름을 누가 설명할 수 있나요?
답변1
sed(에스트레메편집하다itor)는 다음에서 실행될 수 있습니다.에스검색 및 바꾸기 모드 사용일반적인 표현. sed 관련 이스케이프가 몇 가지 있지만 정규 표현식 자체의 경우 다음에서 통역사 도구를 부여할 수 있습니다.정규식:
(
그룹 #1을 캡처합니다.여러 토큰을 함께 그룹화하고 캡처링 그룹을 만들어 하위 문자열을 추출하거나 역참조를 사용하세요.
^
시작.문자열의 시작 부분과 일치합니다.
|
번갈아.이는 부울 OR처럼 작동합니다. 앞이나 뒤의 표현식과 일치합니다 |
.
[^
세트를 부정합니다.세트에 없는 모든 문자와 일치합니다.
0-9
범위."0"에서 "9" 범위의 문자와 일치합니다. 대소문자를 구분합니다.
.
특징."." 기능과 일치합니다.
]
)
(
그룹 #2를 캡처합니다.여러 토큰을 함께 그룹화하고 캡처링 그룹을 만들어 하위 문자열을 추출하거나 역참조를 사용하세요.
[
문자 집합.세트의 모든 문자와 일치합니다.
0-9
범위."0"에서 "9" 범위의 문자와 일치합니다. 대소문자를 구분합니다.
]
+
수량자.앞의 토큰 중 1개 이상과 일치합니다.
)
(
그룹 #3을 캡처합니다.여러 토큰을 함께 그룹화하고 캡처링 그룹을 만들어 하위 문자열을 추출하거나 역참조를 사용하세요.
[
문자 집합.세트의 모든 문자와 일치합니다.
0-9
범위."0"에서 "9" 범위의 문자와 일치합니다. 대소문자를 구분합니다.
]
{3}
수량자.이전에 표시된 매치 3.
)
답변2
이 패턴은 (1) 선의 시작 부분이나 숫자나 점이 아닌 항목, (2) 임의의 숫자, 최소 한 자리, (3) 정확히 세 자리를 캡처합니다. 그런 다음 (2)와 (3) 사이에 쉼표를 사용하여 다시 제자리에 배치하여 효과적으로 천 단위 구분 기호를 추가합니다. 첫 번째 그룹은 소수점 이하 소수점 부분을 만지지 않으면 1.2345
됩니다 1.2,345
.
()
패턴은 기본 정규 표현식(BRE)으로 작성되었으며, 이를 특별하게 만들 려면 각 패턴 앞에 백슬래시를 추가해야 합니다 {}
. 게다가 꼭 필요한 것도GNU sed, BRE의 \+
확장 \|
도 특별한 의미를 갖습니다.. 이 명령은 확장 정규식( sed -E
많은 sed 구현에서 지원됨)으로 작성하는 것이 가장 좋습니다.
sed -E 's/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g'
또한 패턴은 한 번만 교체하며 동일한 숫자에 수천 개의 구분 기호를 추가하지 않습니다. 마지막 항목은 /g
같은 줄에서 여러 번 일치하지만 이미 대체된 데이터는 처리하지 않습니다. 1234567
될 것이다 1234,567
, 그렇지 않을 것이다 1,234,567
. 이 문제를 해결하려면 루프를 추가해야 합니다.
sed -E -e :a -e 's/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g' -e ta
여기, :a
그냥 라벨, 마지막ta
티교체가 성공했는지 테스트하고 교체가 완료되었는지 여부로 돌아가 a
실제로 작업을 수행하는 것과 동일한 횟수만큼 프로세스를 반복합니다. 그래서 1234567
그것은 될 것입니다 1,234,567
.
답변3
sed 's/foo/bar/g' number.txt
: 파일을 읽고number.txt
정규식 패턴을foo
로 바꿉니다bar
. 이는 각 줄의 모든 일치 항목에 대해 발생합니다( )/g
.\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)
: 교체할 패턴입니다. 이스케이프된 괄호 안의 각 부분은\(…\)
"캡처 그룹"입니다. 내부 패턴은 나중에 사용하기 위해 "캡처"됩니다.\(^\|[^0-9.]\)
: 줄의 시작 부분^
이나\|
숫자나 마침표가 아닌 문자를 찾습니다[^0-9.]
. 이것은 본질적으로 숫자 앞의 문자를 찾습니다.\([0-9]\+\)
: 하나 이상의 숫자를 찾습니다[0-9]\+
.\([0-9]\{3\}\)
: 3개의 숫자를 찾으세요[0-9]\{3\}
.
\1\2,\3
: 위 일치 항목을 처음 두 캡처 그룹으로 바꾼 다음,
마지막 캡처 그룹으로 바꿉니다. 즉,,
두 번째 패턴과 세 번째 패턴 사이에 삽입합니다.
'욕심'이 강하기 때문에 sed
경기 시간을 최대한 늘리려고 한다. 따라서 최종 캡처 그룹은 숫자의 마지막 세 자리가 됩니다.
및 \
와 같은 많은 "특수" 문자가 이스케이프 처리됩니다 . "확장 정규식"을 사용하거나 지원하는 경우 이를 이스케이프할 필요가 없습니다. 이렇게 하면 가독성이 향상됩니다.\(…\)
\{3\}
sed
-E
-r