![고쳐 쓰다](https://linux55.com/image/178730/%EA%B3%A0%EC%B3%90%20%EC%93%B0%EB%8B%A4.png)
테이블의 필드를 나타내는 데이터 열이 포함된 플랫 파일이 있습니다. 외부 소스에서 이 파일을 가져와 데이터베이스의 테이블에 데이터를 삽입하려고 합니다. 안타깝게도 제가 받은 파일의 특정 열에 필드(새 필드 추가)가 누락되었습니다. 나에게 전송된 내용을 제어할 수 없으므로 파일을 편집하고 필드만 추가하고 싶습니다. sed
각 행의 특정 열에 텍스트를 추가하는 데 사용할 수 있습니까 ?
예를 들어 다음 파일이 있다고 가정해 보겠습니다.
Alan Bradford 555-2012
Cathy Davies 555-7823
Edward Farris 555-9162
Gary Hobbs 555-5151
Irene Jacobs 555-1285
파일에 지역번호가 없어서 213
앞에 추가하고 싶습니다. 전화번호는 항상 31열(일반 문자 수)에서 시작된다는 것을 알고 있습니다. 그래서 보여주고 싶어
Alan Bradford 213 555-2012
Cathy Davies 213 555-7823
Edward Farris 213 555-9162
Gary Hobbs 213 555-5151
Irene Jacobs 213 555-1285
나는 이것을 3번의 패스로 할 수 있다는 것을 알고 있습니다. cut -c1-30
파트 1을 사용하고 얻을 수 있으며 , cut -c31-
파트 2도 얻을 수 있습니다. 그런 다음 모두 함께 붙여넣을 수 있습니다.echo "$Part1 $NEWDATA $Part2" >> filename
sed를 사용하는 더 쉬운 방법이 있는지 알고 싶습니다. 나는 다음과 같은 것을 사용할 수 있어야한다
sed -e "30l,i213 " InFile > OutFile
한 줄에 30자 이상을 이동한 다음 213
.
잘라서 붙여넣기 옵션보다 무엇이 효과가 있거나 더 나은지 아는 사람이 있나요?
고쳐 쓰다
나는 내 예가 충분히 정확하지 않으며 사람들의 시간 낭비를 막기 위해 질문을 편집해야 한다는 말을 들었습니다. 제가 제시한 예는 이 문제에 대해 매우 정확합니다. 문자열 "XXX"를 Y 위치 앞이나 뒤에 오는 것과 상관없이 항상 Y 위치에 삽입하는 방법은 무엇입니까?
하지만 문제 없습니다. 여기에 제 실제 사례가 있습니다. 각 줄에 928자를 포함하는 텍스트 파일이 있습니다. 878번 위치부터 문자열을 삽입하고 싶습니다. 삽입하려는 위치 뒤의 다음 필드는 메모 필드이므로 일반적으로 비어 있지만 항상 비어 있는 것은 아니기 때문에 문자열 앞과 뒤의 값이 매번 동일할 수는 없습니다.
@DonHolgo의 답변은 가장 유망하고 좋은 답변입니다. 하지만 제가 선호하는 UNIX(AIX 7.1)에서는 오류가 발생하기 전에 최대 255자까지만 추적할 수 있는 것 같습니다.
여기서는 255열에 "XXX"를 삽입합니다.
# sed 's/.\{255\}/&XXX /' OrigTextFile
1 030680001001YNPO 14 H502 000595000000000000 1 0000680M00000100000004799000000000000479900000004799000000004799000000000000479900000 SDI42028820 20P561292 00000000000XXX 000000000000000000000000000000000000000000000000000000000000000 T 0000655000000000Y 0000516000000000E 0000280000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 20200814
하지만 256열 이상에 동일한 연산을 삽입해 보았습니다.
# sed 's/.\{256\}/&XXX /' OrigTextFile
sed: 0602-404 Function s/.\{256\}/&XXX / cannot be parsed.
내 sed 버전에 제한이 있는 것 같습니다. 따라서 텍스트 파일을 자르려는 원래 계획을 따라야 할 수도 있습니다. File1 = 텍스트 파일의 각 줄의 처음 878자 File2 = 추가하려는 새 문자열, 원본 파일의 한 줄에 하나씩 File3 = 원본 텍스트 파일의 나머지 문자.
그런 다음 합류하세요:
# paste File1 File2 File3 > NewTextFile
답변1
당신은 그것을 사용할 수 있습니다
sed 's/.\{30\}/&213 /' InFile > OutFile
처음 30자("모든 문자" x 30)를 자체( &
) + "213"으로 바꿉니다.
답변2
계산 RE를 사용할 수 있습니다. 예를 들어 x{12}
12개의 x
문자가 일치하고 y{1,3}
1, 2 또는 3 y
개의 문자가 일치됩니다. 여기서는 .{30}
30자(즉, 임의의 30자)와 일치하는 와일드카드를 사용합니다 . 결과 \1
문자열에서 패턴 일치에서 괄호로 묶인 참조와 일치합니다.
sed -r 's#^(.{30})#\1213 #' file
업데이트된 질문에서 이제 삽입하기 전에 878자가 있다고 말합니다. 따라서 예시의 30을 실제로는 878로 변경하고 삽입하면 됩니다.XXX
sed -r 's#^(.{878})#\1XXX#' file
고정 너비 수정에도 동일한 프로세스를 적용할 수 있습니다.
perl
일부 구현을 괴롭히는 줄 길이 제한이 없는 것을 사용할 수도 있습니다 sed
.
perl -pe 's#^(.{878})#$1XXX#' file
답변3
다음을 사용해 볼 수도 있습니다.awk
awk '{sub(/^.{30}/,"&213 ")}1' file
213
이는 행의 처음 30자로 구성된 패턴에 추가됩니다 .
구문은 다음과 같습니다.
- 이
sub()
기능은 대체하는 데 사용됩니다.첫 번째지정된 정규식은 현재 줄(또는 작동하도록 명시적으로 지정된 문자열이 없는 경우 기본 대상)에 나타납니다. - 정규식은
^.{30}
"모든 문자 30번"을 의미하지만 줄의 시작 부분부터 시작합니다( "앵커"를 의미^
). - 대체는 "발견된 패턴(의 의미 ) 과 공백이
&
뒤따르는 것 입니다.213
213
줄의 나머지 부분은 변경되지 않고 처음 30자 뒤에 삽입됩니다.
이 작업은 모든 라인에서 수행됩니다( { ... }
무조건 작업 블록). 그러면 awk
수정된 줄( 프로그램 1
끝 부분 awk
)이 인쇄됩니다.
답변4
도구의 외부 한계에 도달하면 다른 방법을 사용하여 877 숫자를 3개 단위, 즉 255와 나머지 112로 나눌 수 있습니다.
skip=877
cmax=255
mult=`expr "$skip" / "$cmax"`
rem=`expr "$skip" % "$cmax"`
lim=".\\{$cmax\\}"
re="\\($lim\\)\\{$mult\\}.\\{$rem\\}"
sed -e "s/$re/&XXX/" your_file_nam
더 쉬운 방법은 다음을 사용하는 것입니다 Perl
.
perl -lpe 'substr($_, 877) =~ s/^/XXX/' your_file_name
파이썬:
python3 -c '
import sys
f, p, r = sys.argv[1:]
p = int(p)
with open(f) as fh:
print(*[l[:p]+r+l[p:] for l in fh],sep="",end="")
' file_name 877 "XXX"