쉼표 앞의 모든 줄에 9자가 포함될 때까지 앞에 0을 추가한 다음 sed를 사용하여 세 자리마다 한 문자를 삽입합니다.

쉼표 앞의 모든 줄에 9자가 포함될 때까지 앞에 0을 추가한 다음 sed를 사용하여 세 자리마다 한 문자를 삽입합니다.

목표는 쉼표 앞의 모든 줄에 9개의 문자가 포함될 때까지 앞에 0을 추가한 다음 세 번째 숫자마다 문자를 삽입하는 것입니다 sed.

입력하다

12345,1s4c3v6s3nh6
123456789,9h5vgbdx34dc
12,7h4f45dcvbgh
1234567,09klijnmh563

현재 결과

[vagrant@localhost ~]$ sed -e 's/\([0-9]\{3\}\),/\/\1\//g' file
12/345/1s4c3v6s3nh6
123456/789/9h5vgbdx34dc
12,7h4f45dcvbgh
1234/567/09klijnmh563

예상되는 결과

000/012/345,1s4c3v6s3nh6
123/456/789,9h5vgbdx34dc
000/000/012,7h4f45dcvbgh
001/234/567,09klijnmh563

노트:

  1. 12345가 되어야 000012345하며 12로 이어져야 합니다 000000012. 즉, 쉼표 앞의 숫자 순서에 중점을 둡니다.
  2. 줄의 형식은 항상 입니다 MAX_9_characters,fixed_12_characters. 즉, 1234512345,1s4c3v6s3nh6입력 파일에 상주하지 않습니다.

문제는 sed를 사용하여 문자 수를 동일하게 만들 수 없다는 것입니다. 이것이 어떻게 가능한지?

답변1

입력의 두 번째 필드에 긴 시퀀스 번호가 없으면 다음을 시도해 보십시오.

$ sed -e 's|^[^,]*|#000000000&|;s|#[^,]*\(.\{9\}\),|\1,|;s|\([0-9]\{3\}\)|\1/|g;s|/\([^0-9]\)|\1|;s|/$||' file
000/012/345,1s4c3v6s3nh6
123/456/789,9h5vgbdx34dc
000/000/012,7h4f45dcvbgh
001/234/567,09klijnmh563

설명하다

  • s|^[^,]*|#000000000&|: 우리는 처음부터 처음까지 모든 것을 일치시키고 ,이를 제조업체와 n개의 숫자 0으로 대체합니다 #. 여기서 n은 우리가 채우려는 길이입니다.

  • s|#[^,]*\(.\{9\}\),|\1,|: 토큰부터 첫 번째까지 모든 것을 일치시키고 ,그 앞의 마지막 9자만 유지하고 ,나머지는 버립니다.

  • s|\([0-9]\{3\}\)|\1/|g: /3자리씩 순서대로 추가합니다.

  • s|/\([^0-9]\)|\1|;s|/$||: after가 /숫자가 아니거나 /줄 끝에 있으면 삭제합니다.

또는 사용하기 더 쉽습니다 perl.

$ perl -F',' -anle '
    $F[0] = sprintf "%09s", $F[0];
    $F[0] =~ s|.{3}|$&/|g;
    chop $F[0];
    print join ",",@F;
' file
000/012/345,1s4c3v6s3nh6
123/456/789,9h5vgbdx34dc
000/000/012,7h4f45dcvbgh
001/234/567,09klijnmh563

답변2

아마도 이 작업을 수행할 수 있지만 sed이는 내 sed-fu의 범위를 벗어납니다. 다른 해결책은 다음과 같습니다.

perl -F, -lane '$F[0]=sprintf("%09s",$F[0]);
                $F[0]=~s#(...)(?!$)#$1/#g;
                print "$F[0],$F[1]"' file

-a각 입력 행을 필드로 분할 하고 @F배열에 저장합니다. 필드 구분 기호를 설정합니다 -F( ,여기). 후행 줄 바꿈을 제거 -l하고 각 호출 끝에 줄 바꿈을 추가하여 print입력 n파일을 한 줄씩 읽고 지정된 스크립트가 -e각 줄에 적용되도록 합니다.

스크립트 자체는 세 가지 작업을 수행합니다. 먼저 첫 번째 필드에 선행( )을 추가하는 데 사용됩니다 sprintf. 그런 다음 첫 번째 필드의 세 문자 집합을 모두 바꿉니다(맨 끝에 있는 문자 제외: )/`. 마지막으로, 이제 수정된 첫 번째 필드, 쉼표 및 두 번째 필드를 인쇄합니다.0$F[0](?!$) with themselves followed by a

답변3

이제 문제가 개선되었으므로 sedGnouc의 답변을 다음과 같이 단순화 할 수 있습니다.

sed 's|^|000000000|;s|.*\(...\)\(...\)\(...,\)|\1/\2/\3|' file

또는 일반 솔루션의 맛을 약간 유지하고 싶다면

sed 's|^|000000000|;s|.*\(.\{3\}\)\(.\{3\}\)\(.\{3\},\)|\1/\2/\3|' file

적어도 다른 답변 중 일부와 마찬가지로 한 줄에 쉼표가 하나만 있다고 가정합니다.

관련 정보