sed에서 중복 대체를 피하는 방법은 무엇입니까?

sed에서 중복 대체를 피하는 방법은 무엇입니까?

첫 번째 파일에는 다음이 포함됩니다.

#. This is the file name to process: waveheight.txt
#. This is the latest data to process if exists: waveheightNew.txt
 FilNam=Project2128/Input/waveheightNew.txt
 if [[ ! -f ${FilNam} ]]; then FilNam=Project2128/Input/waveheight.txt; fi

두 번째 파일에는 다음이 포함됩니다.

#. This is the file name to process: waveheightBin.txt
#. This is the latest data to process if exists: waveheightNewBin.txt
 FilNam=Project2128/Input/waveheightNewBin.txt
 if [[ ! -f ${FilNam} ]]; then FilNam=Project2128/Input/waveheightBin.txt; fi

.txtBin.txt이제 ?로 변경하여 파일을 처리 해야 합니다 . 를 사용하면 두 번째 파일이 sed "s/.txt/Bin.txt/"생성됩니다 . 그때 BinBin.txt쯤이면 어색해 보였을 겁니다.sed "s/Bin.txt/.txt/"sed "s/.txt/Bin.txt/"

불필요한 경기는 건너뛰는 것이 더 현명할까요?

답변1

Bin텍스트에 바꾸려는 항목이 있는 경우 이를 포함하면 해당 항목 자체가 대체됩니다 .

sed 's/\(Bin\)\{0,1\}\.txt/Bin.txt/g'

또는 sedERE를 지원하는 경우 -E(또는 -r일부 이전 버전의 GNU 또는 busybox sed):

sed -E 's/(Bin)?\.txt/Bin.txt/g'

Beware는 .모든 단일 문자와 일치하는 정규식 연산자입니다. \.텍스트를 일치 시켜야 합니다.가리키다.

답변2

Perl Negative LookBehind를 사용하여 일치시킬 수 있지만 .txt그렇지 않습니다 Bin.txt.

perl -pe 's/(?<!Bin)\.txt/Bin.txt/g'

따라서 테스트하려면 다음을 수행하십시오.

$ echo 'Bin.txt foo.txt' | perl -pe 's/(?<!Bin)\.txt/Bin.txt/g'
Bin.txt fooBin.txt

불행하게도 sed이 구성은 제공되지 않습니다.

답변3

를 사용하여 조건부 대체를 수행할 수 있습니다 sed. 예를 들어 행이 이미 포함되어 있는지 테스트 Bin.txt하고 포함되지 않은 경우에만 대체를 수행할 수 있습니다.

sed '/Bin\.txt/!s/\.txt/Bin.txt/'

이는 행당 하나의 교체만 필요하다고 가정합니다.

질문에 힌트를 주었지만 동일한 호출 내에서 무조건 대체를 수행한 다음 오류가 있으면 수정할 수도 있습니다 sed.

sed -e 's/\.txt/Bin.txt/' -e 's/BinBin/Bin/'

답변4

GNU-sed다음과 같이 이 작업을 수행 할 수 있습니다 .

echo "$Filnam" |\
sed -e '
   s/\.txt/\n&/;T   # try to place a newline marker to the left of .txt, quit if unsuccessful
   s/Bin\n/Bin/;t   # If the marker turned out to be just to the right of Bin => Bin.txt already 
                    # existed in the name, so we needn"t do anything n take away the marker n quit
   s/\n/Bin/        # Bin could not be found adjacent to .txt so put it n take away the marker as well
'

### Below is the POSIX sed code for accomplishing the same:
sed -e '
    s/\.txt/\
&/;/\n/!b
    s/Bin\n/Bin/;/\n/!b
    s/\n/Bin/
'

관련 정보