저는 컴퓨터와 상호작용하는 데 있어서 완전 초보자인데, 스크립트를 작성하지 않고는 따라갈 수 없는 프로젝트를 진행하고 있어서 도움이 필요합니다.
내 파일의 한 줄에 두 개의 문자열이 있고 sed를 사용하여 이를 바꾸고 싶습니다. 문제는 그것들이 매우 유사하고 독립적으로 교체하는 방법을 모른다는 것입니다.
내가 바꾸고 싶은 줄은 다음과 같습니다.
*xyzfile 0 1 somefilebeingpointedto.xyz
나는 이 줄로 끝내고 싶다:
*xyz 0 1
파일 간에 0과 1이 변경되고 마지막 문자열의 ".xyz" 앞에 보수적인 문자열이 없기 때문에 이 작업을 수행하는 방법이나 단순히 전체 줄을 바꾸는 방법을 모르겠습니다.
나는 다음 두 줄의 sed를 사용하려고했습니다.
sed -i 's/^.*xyzfile/\*xyz/' myfile.inp
sed -i 's/^.\.xyz/" "/' myfile.inp
순서는 아무런 차이가 없습니다. sed는 마침표를 두 번째 줄의 문자열 일부로 전혀 고려하지 않는 것 같습니다.
이것을 달성할 수 있는 더 좋은 방법이 있다면, 저는 모두 귀를 기울일 것입니다! 감사해요
답변1
두 번째 예의 문제점은 라인과 전혀 일치하지 않는다는 것입니다. 일치를 시도합니다 ^.\.xyz
. 즉, <beginning of line><any character>.xyz
. 하지만 당신이 일치시키려고 하는 것 같아요 <some characters>.xyz<end of line>
. 지금까지는 삭제해야 하며 상황에 맞게 정의하는 ^
방법을 찾아야 합니다 .<some characters>
하지만 두 번의 sed 호출은 필요하지 않습니다.홀드 모드sed에서. 원하는 패턴을 둘러싸면유지하다\1
(이스케이프 처리된) 괄호를 사용하면 나중에 이를 (또는 \2
두 번째 패턴 등) 로 바꿀 수 있습니다 .
file
따라서 마지막 파일 이름을 제거하고 싶습니다 .
*xyzfile 0 1 somefilebeingpointedto.xyz
그래서 나는 모드생각하다당신이 찾고 있는 것은 ("file"이라는 텍스트를 포함하는) 것입니다:
<something to keep>file<something to keep><space><pattern without spaces until end of line>
이를 다음과 결합할 수 있습니다.
^\(.*\)file\(.*\) [^ ]*$
유지하려는 두 부분은 (이스케이프된) 괄호 안에 있습니다. 나중에 사용하기 위해 보관하고 싶지 않으면 대괄호( .*file.* [^ ]*
) 를 제거할 수 있습니다.
다음으로 sed를 대체하면 다음과 같은 완전한 라인을 얻게 됩니다.
sed 's/^\(.*\)file\(.*\) [^ ]*$/\1\2/'
답변2
정규 표현식의 sed 도트 표현어떤 역할이든, 그러나 단지하나성격.
따라서 정규식은 ^.\.xyz
다음을 의미합니다. 줄의 시작 부분부터 시작하여 일치합니다.하나문자, 점, 을 xyz
의미할 수도 있지만 ^.*\.xyz$
이는 일치합니다 .모두라인(그리고 삭제). 공백을 구분 기호로 사용해야 합니다(파일 이름에 공백이 없다고 가정). [^ ]*\.xyz$
즉, 공백( )부터 시작하여 줄 끝의 확장자 ( )까지 공백이 아닌 " "
( ) 여러 문자( )를 일치시킵니다 . 각 부분 앞에 ::을 사용하면 이 두 대체를 표현할 수 있습니다.*
[^ ]
.xyz
$
-e
sed -e 's/^.*xyzfile/*xyz/' -e 's/ [^ ]*\.xyz$//' myfile.inp
*
오른쪽의 교체를 탈출할 필요가 없습니다 .
이는 다음과 같이 단순화될 수 있습니다.
sed -e 's/xyzfile /*xyz /' -e 's/ [^ ]*\.xyz$//' myfile.inp
파일 이름의 공백
파일 이름에 공백이 포함된 경우 줄의 해당 부분만 선택하는 쉬운 방법이 없기 때문에 정규 표현식이 더 복잡해집니다.
두 번째와 세 번째 필드에 문자가 하나만 있는 경우 캡처 대괄호를 사용하여 다시 넣을 수 있습니다 \1
.
sed -e 's/xyzfile\( . .\) .*\.xyz$/xyz\1/' myfile.inp
존재하다확장하다정규식 구문:
sed -E -e 's/xyzfile( . .) .*\.xyz$/xyz\1/' myfile.inp
또는 필드에 여러 문자(공백 제외)가 포함될 수 있는 경우:
sed -E -e 's/xyzfile( [^ ]* [^ ]*) .*\.xyz$/xyz\1/' myfile.inp
xyzfile
줄이 (no ) 와 같으면 실패할 수 있습니다.
*xyzffff 0 1 pointedto.xyz
이 경우 각 교체를 독립적으로 적용합니다.
sed -E -e 's/xyzfile /xyz /' -e 's/( [^ ]* [^ ]*) .*\.xyz$/\1/' myfile.inp