목표는 쉼표 앞의 모든 줄에 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
노트:
12345
가 되어야000012345
하며12
로 이어져야 합니다000000012
. 즉, 쉼표 앞의 숫자 순서에 중점을 둡니다.- 줄의 형식은 항상 입니다
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
이제 문제가 개선되었으므로 sed
Gnouc의 답변을 다음과 같이 단순화 할 수 있습니다.
sed 's|^|000000000|;s|.*\(...\)\(...\)\(...,\)|\1/\2/\3|' file
또는 일반 솔루션의 맛을 약간 유지하고 싶다면
sed 's|^|000000000|;s|.*\(.\{3\}\)\(.\{3\}\)\(.\{3\},\)|\1/\2/\3|' file
적어도 다른 답변 중 일부와 마찬가지로 한 줄에 쉼표가 하나만 있다고 가정합니다.