현재 경로 대신 전체 경로를 사용할 때마다 "이름 바꾸기"가 다르게 동작하는 이유는 무엇입니까?

현재 경로 대신 전체 경로를 사용할 때마다 "이름 바꾸기"가 다르게 동작하는 이유는 무엇입니까?

알았어 난 그래질문에 답하다OP에는 Ubuntu에 여러 저장소가 있어 관련되지 않은 소프트웨어를 설치할 때 문제가 발생할 수 있습니다. 단일 라이너를 사용하여 PPA를 비활성화 rename한 다음 일련의 지침을 따르는 것이 좋습니다. 다 괜찮습니다. 질문에 대답은 남겨두겠습니다...아니요. 결과는 rename내가 기대했던 것과 달랐습니다.

sudo rename s/list/list\.disable/g /etc/apt/sources.list.d/*.list

/etc/apt/sources.list.d/이를 통해 rename은 로 끝나는 모든 파일을 보고 .list.list바꿀 것으로 예상합니다 .list.disable. 거의 동일한 명령으로 다른 답변을 얻었지만 OP는 피드백을 제공하지 않았으며 먼저 테스트하지 않은 상황에 있습니다. 이 이론은 다음에 폐기되었습니다. 놀랍게도 OP는 다음 줄에서 문제를 발견했습니다.

Can't rename /etc/apt/sources.list.d/iaz-battery-status-quantal.list /etc/apt/sources.list.disable.d/iaz-battery-status-quantal.list.disable: No such file or directory
Can't rename /etc/apt/sources.list.d/ubuntu-wine-ppa-quantal.list /etc/apt/sources.list.disable.d/ubuntu-wine-ppa-quantal.list.disable: No such file or directory
Can't rename /etc/apt/sources.list.d/webupd8team-java-raring.list /etc/apt/sources.list.disable.d/webupd8team-java-raring.list.disable: No such file or directory

이상한 느낌이 들어서 이 이론을 직접 테스트해 보았는데 같은 결과가 나왔습니다. 그 다음에,문제가 발생할 때마다 일반적으로 정규 표현식이 아닌 정규 표현식을 사용합니다.? 나는 많은 뒤틀린 방식으로 정규식을 변경했습니다.

  • s/.list/.list.disable/g
  • s/.list/.list.disable/g
  • /목록/list.disable/
  • 다른 조합은 기억이 안나는데

글쎄요, 저는 정규식이 문제라고 생각하지 않았기 때문에 선택기를 눈여겨 본 다음 이를 변경 /etc/apt/sources.list.d/*하고 정규식 테스트를 재활용했습니다. 기쁨이 없습니다. 조금 답답해서 touch some.list명령을 적용했습니다.

rename s/\.list/\.list\.disable/g *

빙고! 이제는 온몸이 통제되는 것 같은 느낌이 듭니다. 나는 대답을 수정하고 내 인생을 계속 이어갔습니다...아니요! 이것은 용납될 수 없습니다. 왜? 매뉴얼을 확인했는데 놀랍게도 현재 경로 예제만 사용하고 있습니다. 이게 정상인가요? 아니면 기능이 구현되지 않아서 그런 걸까요? 아니면 내 이론을 믿지 않기 시작해야 할까요?

답변1

-n매개변수를 사용하여 테스트 실행 모드로 실행합니다 rename. 이는 모드를 테스트할 때 유용합니다.

martin@martin ~ % rename -n s/list/list.disable/g /etc/apt/sources.list.d/*.list | sed 's/renamed as/\n =>/g'
[...]
/etc/apt/sources.list.d/spotify.list 
 => /etc/apt/sources.list.disable.d/spotify.list.disable
/etc/apt/sources.list.d/steam.list 
 => /etc/apt/sources.list.disable.d/steam.list.disable
[...]

여기서 명백한 오류는 패턴 list일치이므로 폴더와 폴더에 포함된 파일의 이름을 바꾸려고 합니다.sources.list.d

대신 이 모드를 사용하십시오:

rename -n 's/\.list$/.list.disable/' /etc/apt/sources.list.d/*.list | sed 's/renamed as/\n =>/g'
[...]
/etc/apt/sources.list.d/spotify.list 
 => /etc/apt/sources.list.d/spotify.list.disable
/etc/apt/sources.list.d/steam.list 
 => /etc/apt/sources.list.d/steam.list.disable
[...]

차이점은 다음과 같습니다.

  1. .검색 패턴에서 를 인용하면 \.점이 문자가 아닌 실제 점과만 일치합니다(정규 표현식에서 따옴표가 없는 점이 일반적으로 수행하는 작업).

  2. 다음 $목록은 "문자열의 끝"을 나타냅니다. 이는 파일 이름 끝에 있는 ".list"만 일치하고 교체되는지 확인하며, 경로나 파일 이름의 다른 부분에 있는 ".list"는 그렇지 않습니다.

  3. 대체 문자열에서 점을 인용할 필요가 없습니다. 따라서 ".list.disable"은 .더 이상 특별한 의미가 없으므로 백슬래시 없이 작동합니다.

  4. 또한 쉘이 어떤 식으로든 정규식을 수정하는 것을 방지하기 위해 정규식을 작은따옴표로 묶었습니다.

답변2

문제는 g실제로 모드를 고정해야 할 때 전역 스위치를 사용하고 있다는 것입니다. 당신이 쓴대로 :

s/a/b/g

문자열의 모든 위치에서 a를 b로 바꿉니다. 이로 인해 존재하지 않는 디렉터리에 대한 경로 이름을 바꾸려고 합니다. 이는 디렉터리에서 작업을 수행할 때 문제가 사라지는 이유이기도 하며, 교체할 일치 항목이 하나만 있습니다.

패턴을 고정시키려는 것 같아요.

s/\.list$/.list.disable/

이렇게 하면 존재하지 않는 디렉터리 /etc/apt/sources.list.disable.d/로 파일을 이동하려는 시도가 방지됩니다(따라서 해당 디렉터리로 파일을 이동할 수 없습니다).

관련 정보