설명하다:

설명하다:

숫자 구성 체계에 다양한 숫자의 선행 0을 추가하기 위해 sed 구문을 단순화하는 데 문제가 있습니다. 내가 조작하는 문자열은 다음과 같습니다.

1.1.1.1,Some Text Here

sed 구문 사용

sed -r ":r;s/\b[0-9]{1,$((1))}\b/0&/g;tr"

나는 반응을 이끌어낼 수 있다

01.01.01.01,Some Text Here

그러나 내가 찾고 있는 것은 필드 2와 3을 최대 2자리로 채우고 필드 4를 최대 3자리로 채워서 모든 항목의 표준 길이가 [0-9]가 되도록 하는 것입니다. [0-9]{ 2}.[0-9]{2}.[0-9]{3}

1.01.01.001,Some Text Here

저는 평생 동안 마침표 뒤의 숫자만 캡처하는 데 필요한 매개변수를 포함하도록 경계를 수정하는 방법조차 모릅니다. 나는 이것이 \b를 사용하는 것과 관련이 있다고 생각합니다. 단어 경계에서 0개의 문자와 일치한다는 것을 이해하지만 일치 항목에 마침표를 추가하려는 시도가 실패하는 이유를 이해하지 못합니다. 다음과 같이:

sed -r ":r;s/\.\b[0-9]{1,$((1))}\b/0&/g;tr"
sed -r ":r;s/\b\.[0-9]{1,$((1))}\b/0&/g;tr"
Both cause the statement to hang

sed -r ":r;s/\b[0-9]\.{1,$((1))}\b/0&/g;tr"
sed -r ":r;s/\b[0-9]{1,$((1))}\.\b/0&/g;tr"
sed -r ":r;s/\b[0-9]{1,$((1))}\b\./0&/g;tr"
cause the statement to output:

1.01.01.1,Some Text Here

또한 문에 다음 텍스트가 포함되어 있으면 추가 문제가 발생할 것으로 예상됩니다.

1.1.1.1,Some Number 1 Here

sed와 그 모든 복잡함을 정말로 배워야 한다는 것은 기정사실이었습니다. 나는 이 문제를 해결하기 위해 노력하고 있지만 이 특정 진술로 인해 한동안 계속해서 문제가 발생할 것으로 예상됩니다. 어떤 도움이라도 대단히 감사하겠습니다.

편집: 방법을 찾았습니다... 이 명령문은 내가 원하는 대로 작동하는 것 같지만 이를 수행하는 더 우아한 방법이 있어야 합니다.

sed -r ':r;s/\b[0-9]{1,1}\.\b/0&/;tr;:i;s/\b[0-9]{1,2},\b/0&/;ti;s/.//'

또한 구문론적으로 말하면 유사한 숫자 형식이 텍스트에 나타나면 문제가 발생할 수 있습니다.

1.1.1.1,Some Text Referring to Document XXX Heading 1.2.3

이 경우 다음과 같은 결과가 발생합니다.

1.01.01.001,Some Text Referring to Document XXX Heading 01.02.03

해결됨 도움을 주셔서 감사합니다. 처음에는 아래 허용된 답변을 사용하여 문제를 해결했습니다. 다음 정렬을 활용하는 더 큰 솔루션의 일부로 이 솔루션을 Python으로 옮기고 싶습니다.

def getPaddedKey(line):
    keyparts = line[0].split(".")
    keyparts = map(lambda x: x.rjust(5, '0'), keyparts)
    return '.'.join(keyparts)

s=sorted(reader, key=getPaddedKey)

답변1

bash가 이를 처리할 수 있습니다. 그러나 Perl보다 훨씬 느립니다.

echo "1.1.1.1,Some Text Here" | 
while IFS=., read -r a b c d text; do
    printf "%d.%02d.%02d.%03d,%s\n" "$a" "$b" "$c" "$d" "$text"
done
1.01.01.001,Some Text Here

답변2

perl구체적으로 해결책을 요구하지는 않았지만 어쨌든 여기에 하나가 있습니다. 나는 개인적으로 이것이 읽기 더 쉽다고 생각합니다. 특히 여러 줄로 나눌 때 더욱 그렇습니다.

먼저 한 줄:

(
    echo '1.2.3.4,Some Text Here'
    echo '1.01.01.1,Some Text Here'
    echo '1.1.1.1,Some Number 1 Here'
    echo '1.1.1.1,Some Text Referring to Document XXX Heading 1.2.3'
    echo '1.2.3.4,Some \n \s \text'
) |
perl -ne '($ip, $text) = split(/,/, $_, 2); $ip = sprintf("%1d.%02d.%03d.%03d", split(/\./, $ip)); print "$ip,$text"'

결과적으로:

1.02.003.004,Some Text Here
1.01.001.001,Some Text Here
1.01.001.001,Some Number 1 Here
1.01.001.001,Some Text Referring to Document XXX Heading 1.2.3
1.02.003.004,Some \n \s \text

다음은 분석되고 주석 처리된 스크립트입니다 (플래그는 perl코드 주위에 -n암시적 루프를 배치합니다 ).while read; do ... done

($ip, $text) = split(/,/, $_, 2);                # Split line into two parts by comma
@octets = split(/\./, $ip)                       # Split IP address into octets by dots
$ip = sprintf("%1d.%02d.%03d.%03d", @octets);    # Apply the formatting
print "$ip,$text"                                # Output the two parts

답변3

용법: leading_zero.sh input.txt

#!/bin/bash

sed -r '
    s/\.([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{1,3},)/.0\1.0\2.00\3/
    s/\.0*([0-9]{2})\.0*([0-9]{2})\.0*([0-9]{3})/.\1.\2.\3/
' "$1"

설명하다:

  1. 첫 번째 대체는 각 숫자에 특정 수의 0을 추가합니다. 1개의 0~2자리 및 3자리, 2개의 0~4자리. 이미 몇 자리가 있는지는 중요하지 않습니다.
  2. 두 번째 대체는 추가 0을 모두 제거하고 필요한 자릿수만 남깁니다. 2, 3개의 숫자에는 2자리 숫자만 포함되어야 합니다. 그대로 두고 나머지는 제거하세요. 네 번째 숫자에는 3자리 숫자만 포함될 수 있습니다. 그대로 두고 나머지는 제거하세요.

입력.txt

1.1.1.1,Some Text Here
1.1.1.1,Some Text Here
1.11.1.11,Some Text Referring to Document XXX Heading 1.2.3
1.1.1.1,Some Text Here
1.1.11.111,Some Text Referring to Document XXX Heading 1.2.3
1.11.1.1,Some Text Here

출력.txt

1.01.01.001,Some Text Here
1.01.01.001,Some Text Here
1.11.01.011,Some Text Referring to Document XXX Heading 1.2.3
1.01.01.001,Some Text Here
1.01.11.111,Some Text Referring to Document XXX Heading 1.2.3
1.11.01.001,Some Text Here

답변4

perl -pe '/^\d/g && s/\G(?:(\.\K\d+(?=\.))|\.\K\d+(?=,))/sprintf "%0".($1?2:3)."d",$&/ge'

설명하다:

여기서 사용되는 접근 방식은 숫자 근처를 살펴보고 그에 따라 행동하는 것입니다. 따라서 두 번째와 세 번째 숫자는 양쪽에 점이 있고, 네 번째 숫자는 왼쪽에 점이 있고 오른쪽에 쉼표가 있습니다.

정규식에서 두 번째 또는 세 번째 숫자가 포함된 경로를 사용하면 $1을 설정하므로 정밀도가 2로 채워집니다. OTOH, 네 번째 숫자의 패딩은 3입니다.

% 고양이 파일.txt

1.00.3.4,Some Text Here
1.01.01.1,Some Text Here
1.0.01.1,Some Number 1 Here
1.1.1.1,Some Text Referring to Document XXX Heading 1.2.3.4
1.2.3.4,Some \n \s \text

결과:

1.00.03.004,Some Text Here
1.01.01.001,Some Text Here
1.00.01.001,Some Number 1 Here
1.01.01.001,Some Text Referring to Document XXX Heading 1.2.3.4
1.02.03.004,Some \n \s \text

관련 정보