여러 패턴을 한 번에 sed로 바꾸는 방법은 무엇입니까?
'abbc'문자열이 있고 바꾸고 싶다고 가정 해보십시오.
- ab-> 기원전
- 기원전-> ab
두 번 교체하려고하면 결과가 원하는 것이 아닙니다.
echo 'abbc' | sed 's/ab/bc/g;s/bc/ab/g'
abab
그렇다면 아래와 같이 대체 할 수있는 sed 명령은 무엇입니까?
echo abbc | sed SED_COMMAND
bcab
편집 : 실제로 텍스트에는 두 가지 이상의 패턴이있을 수 있으며 필요한 교체 수를 알 수 없습니다. sed
스트림 편집기 라는 답변이 있었고 그 대체품은 탐욕스럽게 생각하기 때문에 스크립트 언어를 사용해야한다고 생각합니다.
아마도 이런 식으로 뭔가 :
sed 's/ab/~~/g; s/bc/ab/g; s/~~/bc/g'
~
문자열에없는 문자로 바꿉니다 .
나는 항상 "-e"와 함께 여러 문장을 사용한다
$ sed -e 's:AND:\n&:g' -e 's:GROUP BY:\n&:g' -e 's:UNION:\n&:g' -e 's:FROM:\n&:g' file > readable.sql
이것은 모든 AND, GROUP BY, UNION 및 FROM 앞에 '\ n'을 추가하는 반면 '&'는 일치하는 문자열을 의미하고 '\ n &'은 일치하는 문자열을 '\ n'앞에 '\ n'으로 바꾸려는 것을 의미합니다. '
다음은 값이 재사용되는 방법을 확인하지 않고 여러 검색 및 바꾸기 쌍에 작동 하는 ooga의 답변 변형입니다 .
sed -i '
s/\bAB\b/________BC________/g
s/\bBC\b/________CD________/g
s/________//g
' path_to_your_files/*.txt
예를 들면 다음과 같습니다.
전에:
some text AB some more text "BC" and more text.
후:
some text BC some more text "CD" and more text.
\b
단어 경계를 나타내 ________
므로 검색을 방해 하지 않습니다 (우분투에서 GNU sed 4.2.2를 사용하고 있습니다). 단어 경계 검색을 사용하지 않으면이 기술이 작동하지 않을 수 있습니다.
또한 명령을 제거 하고 명령 끝에 s/________//g
추가 하는 것과 동일한 결과를 제공 && sed -i 's/________//g' path_to_your_files/*.txt
하지만 경로를 두 번 지정할 필요는 없습니다.
jthill이 제안한 것처럼 파일에 null이 표시되지 않는 것을 알고 있다면 대신 \x0
또는 _\x0_
대신 사용하는 것이 변형입니다 .________
sed
스트림 편집기입니다. 탐욕스럽게 검색하고 교체합니다. 요청한 것을 수행하는 유일한 방법은 중간 대체 패턴을 사용하고 결국 다시 변경하는 것입니다.
echo 'abcd' | sed -e 's/ab/xy/;s/cd/ab/;s/xy/cd/'
이것은 당신을 위해 일할 수 있습니다 (GNU sed) :
sed -r '1{x;s/^/:abbc:bcab/;x};G;s/^/\n/;:a;/\n\n/{P;d};s/\n(ab|bc)(.*\n.*:(\1)([^:]*))/\4\n\2/;ta;s/\n(.)/\1\n/;ta' file
이 테이블은 보류 공간 (HS)에서 준비된 후 각 행에 추가되는 찾아보기 테이블을 사용합니다. 고유 한 마커 (이 경우 \n
)가 줄의 시작 부분에 추가되고 줄 길이 전체에서 검색을 범프하는 방법으로 사용됩니다. 마커가 라인의 끝에 도달하면 프로세스가 완료되고 조회 테이블과 마커가 삭제됩니다.
NB 룩업 테이블은 시작시 준비되고 :
대체 문자열과 충돌하지 않도록 선택된 두 번째 고유 마커 (이 경우 )를 준비합니다.
일부 의견 :
sed -r '
# initialize hold with :abbc:bcab
1 {
x
s/^/:abbc:bcab/
x
}
G # append hold to patt (after a \n)
s/^/\n/ # prepend a \n
:a
/\n\n/ {
P # print patt up to first \n
d # delete patt & start next cycle
}
s/\n(ab|bc)(.*\n.*:(\1)([^:]*))/\4\n\2/
ta # goto a if sub occurred
s/\n(.)/\1\n/ # move one char past the first \n
ta # goto a if sub occurred
'
테이블은 다음과 같이 작동합니다.
** ** replacement
:abbc:bcab
** ** pattern
Tcl에는이 기능이 내장 되어 있습니다
$ tclsh
% string map {ab bc bc ab} abbc
bcab
현재 위치에서 시작하는 문자열 비교를 수행하여 문자열을 한 번에 한 문자 씩 걷는 것으로 작동합니다.
펄에서 :
perl -E '
sub string_map {
my ($str, %map) = @_;
my $i = 0;
while ($i < length $str) {
KEYS:
for my $key (keys %map) {
if (substr($str, $i, length $key) eq $key) {
substr($str, $i, length $key) = $map{$key};
$i += length($map{$key}) - 1;
last KEYS;
}
}
$i++;
}
return $str;
}
say string_map("abbc", "ab"=>"bc", "bc"=>"ab");
'
bcab
May be a simpler approach for single pattern occurrence you can try as below: echo 'abbc' | sed 's/ab/bc/;s/bc/ab/2'
My output:
~# echo 'abbc' | sed 's/ab/bc/;s/bc/ab/2'
bcab
For multiple occurrences of pattern:
sed 's/\(ab\)\(bc\)/\2\1/g'
Example
~# cat try.txt
abbc abbc abbc
bcab abbc bcab
abbc abbc bcab
~# sed 's/\(ab\)\(bc\)/\2\1/g' try.txt
bcab bcab bcab
bcab bcab bcab
bcab bcab bcab
Hope this helps !!
Here is an awk
based on oogas sed
echo 'abbc' | awk '{gsub(/ab/,"xy");gsub(/bc/,"ab");gsub(/xy/,"bc")}1'
bcab
참고URL : https://stackoverflow.com/questions/26568952/how-to-replace-multiple-patterns-at-once-with-sed
'Programing' 카테고리의 다른 글
자바 스크립트에서 [] .slice.call에 대한 설명은 무엇입니까? (0) | 2020.05.18 |
---|---|
Windows 배치 파일에서 시스템 환경 변수를 설정 하시겠습니까? (0) | 2020.05.18 |
OpenSSL을 사용하여 PKCS # 12 인증서를 PEM으로 변환 (0) | 2020.05.17 |
로딩 상태에있을 때 버튼에 스피너 아이콘을 추가하는 방법은 무엇입니까? (0) | 2020.05.17 |
잡히지 않은 TypeError : 정의되지 않은 'msie'속성을 읽을 수 없습니다-jQuery 도구 (0) | 2020.05.17 |