다음과 같은 파일이 있습니다.
1;1471375551;joe;WO12344;
2;1471378551;frank;WO12345;1471380211
3;1471383211;frank;WO12345;1471385211
4;1471385311;frank;WO12345;
5;1471385311;joe;WO12346;1471388211
frank
bash 스크립트를 사용하여 지정된 이름(예: )과 지정된 WO 번호(예: WO12345
)를 포함하고 다음으로 끝나는 줄을 찾은 ;
다음 줄 끝에 문자열을 추가하고 싶습니다 . stdout으로 출력하는 대신 파일을 직접 편집하고 싶습니다. read
이름과 WO 번호를 얻는 방법을 알고 있습니다 . 나는 sed
with -i
가 올바른 도구라고 생각합니다 . 어떻게 해야 하나요?
답변1
이름과 WO가 항상 연속적이라면 간단합니다.
sed '/frank;WO12345;/s/;$/;sometext/' -i file
어떤 방식으로든 나타날 수 있거나 반드시 서로 옆에 있을 필요는 없는 경우 명령 블록을 사용하여 두 테스트를 결합합니다.
sed '/;frank;/{/;WO12345;/s/;$/;sometext/}' -i file
답변2
awk
필드로 구분된 데이터에 더 적합합니다.
사용 awk
:
awk -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' file.txt
;Foobar
끝에 삽입하려는 항목으로 바꾸십시오 .
여기서는 분리된 세 번째와 네 번째 필드가 필수 문자열과 일치하는지 확인하고 ;
, 그렇다면 ;Foobar
끝에 문자열을 추가합니다.
최신 GNU awk
(>=4.10)에는 내부 편집 옵션이 있습니다:
awk -i inplace -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' file.txt
sponge
GNU moreutils
또는 임시 파일 의 기능을 사용 하지 않는 경우 :
awk -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' file.txt | sponge file.txt
awk -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' \
file.txt >file_temp.txt && mv file_temp.txt file.txt
당신이 주장하는 경우 sed
:
sed -Ei '/^([^;]*;){2}frank;WO12345;/ s/$/;Foobar/' file.txt
([^;]*;){2}
처음 두 필드와 일치하고 세 번째와 네 번째 필드가 필수인지 확인한 다음 교체를 완료합니다.
예:
$ cat file.txt
1;1471375551;joe;WO12344;
2;1471378551;frank;WO12345;1471380211
3;1471383211;frank;WO12345;1471385211
4;1471385311;frank;WO12345;
5;1471385311;joe;WO12346;1471388211
$ awk -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' file.txt
2;1471378551;frank;WO12345;1471380211;Foobar
3;1471383211;frank;WO12345;1471385211;Foobar
4;1471385311;frank;WO12345;;Foobar
$ sed -E '/^([^;]*;){2}frank;WO12345;/ s/$/;Foobar/' file.txt
1;1471375551;joe;WO12344;
2;1471378551;frank;WO12345;1471380211;Foobar
3;1471383211;frank;WO12345;1471385211;Foobar
4;1471385311;frank;WO12345;;Foobar
5;1471385311;joe;WO12346;1471388211