숫자 조직 구성표에 다양한 수의 선행 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
그러나 내가 찾고있는 것은 모든 항목의 표준 길이가 [0-9]에 있도록 필드 2와 3에서 최대 2 자리, 필드 4에서 3 자리까지 0으로 채우는 것입니다. [0-9] { 2}. [0-9] {2}. [0-9] {3}
1.01.01.001,Some Text Here
내 인생에서 나는 마침표 뒤에 오는 숫자에만 스냅하는 데 필요한 매개 변수를 포함하도록 경계를 수정하는 방법조차도 알 수 없습니다. 단어 경계에서 0 문자와 일치하는 것으로 이해하는 \ b를 사용하는 것과 관련이 있다고 생각하지만 일치에 마침표를 추가하려는 시도가 다음과 같이 실패하는 이유를 이해하지 못합니다.
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)
답변
용법: 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"
설명:
- 첫 번째 치환은 각 숫자에 일정한 양의 0을 더합니다. 1 0 ~ 2 및 3 숫자, 2 0 ~ 4 숫자. 아무리 많은 숫자가 이미 있는지는 중요하지 않습니다.
- 두 번째 substution은 여분의 0을 모두 제거하고 필요한 수의 숫자 만 남겨 둡니다. 2와 3 숫자는 2 자리 숫자 만 포함해야합니다. 그들을 떠나 휴식을 제거합니다. 네 번째 숫자는 3 자리 숫자 만 포함해야합니다. 그들을 떠나 휴식을 제거합니다.
input.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
output.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
답변
bash는 이것을 처리 할 수 있습니다. 그래도 펄보다 훨씬 느릴 것입니다 :
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
답변
구체적으로 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
답변
가능한 접근 방법은 다음과 같습니다.
sed -E 's/([0-9]*\.)/0\1/g;s/.//;s/([0-9]*,)/00\1/'
예
echo "1.11.111.1111,Some Text Here" | sed -E 's/([0-9]*\.)/0\1/g;s/.//;s/([0-9]*,)/00\1/'
1.011.0111.001111,Some Text Here
이 문자열로도 작업하십시오.
echo "1.1.1.1,Some Number 1 Here" | sed -E 's/([0-9]\.)/0\1/g;s/.//;s/([0-9],)/00\1/'
1.01.01.001,Some Number 1 Here
… 그리고이 문자열 :
echo "1.2.2101.7191,Some Text Here" | sed -E 's/([0-9]*\.)/0\1/g;s/.//;s/([0-9]*,)/00\1/'
1.02.02101.007191,Some Text Here
답변
perl -pe '/^\d/g && s/\G(?:(\.\K\d+(?=\.))|\.\K\d+(?=,))/sprintf "%0".($1?2:3)."d",$&/ge'
설명:
여기에 사용 된 방법은 숫자의 주변을보고이를 기반으로 조치를 취하는 것입니다. 따라서 두 번째와 세 번째 숫자는 양쪽에 점이 표시되고 4 번째 숫자는 왼쪽에 점이 표시되고 쉼표는 오른쪽에 표시됩니다.
$ 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