다음 파일 목록이 있습니다.
$ find .
.
./ sdf.sdf
./ dkfjd L
./aaa*
./aaa*bbb
./aaa:bbb
./b
./b/c
./b/c/xxx.123
이렇게 하면 rename -n -e 's/\*|\:/_/g' -e 's/^\ +//' *
내가 원하는 것을 얻을 수 있습니다.
' sdf.sdf' would be renamed to 'sdf.sdf'
' dkfjd L' would be renamed to 'dkfjd L'
'aaa*' would be renamed to 'aaa_'
'aaa*bbb' would be renamed to 'aaa_bbb'
'aaa:bbb' would be renamed to 'aaa_bbb'
하지만 이렇게 하면 다음과 같은 find . | rename -n -e 's/\*|\:/_/g' -e 's/^\ +//'
결과를 얻습니다.
Reading filenames from STDIN
'./aaa*' would be renamed to './aaa_'
'./aaa*bbb' would be renamed to './aaa_bbb'
'./aaa:bbb' would be renamed to './aaa_bbb'
두 번째 명령에서 공백으로 시작하는 디렉터리가 표시되지 않는 이유는 무엇입니까?
저도 그렇게 해봤는데 find . -print0 | rename -n -0 -e 's/\*|\:/_/g' -e 's/^\ +//'
별 차이가 없었어요.
큰 트리에서 작업 해야 합니다 rename
. 하위 디렉터리로 재귀할 수 있는 다른 방법이 있습니까?
참고: 결국에는 mdfind
이 옵션을 사용할 수 없게 되므로 find
해당 옵션을 사용할 수 없습니다 -exec
.
답변1
그러면 파일과 디렉터리의 이름이 변경됩니다(실제로는 일치하는 모든 항목). -depth
내용이 안전하게 삭제될 때까지 더 높은 수준의 디렉터리 이름이 바뀌지 않도록 지정했습니다 .
find . -depth | rename -n -e 'y{*:}{_}; s{(?<=/)\s+(?!.*/.*$)}{}'
이름 바꾸기는 두 개의 RE로 구성됩니다. (저는 rename
하나의 매개변수만 허용하므로 -e {RE}
두 작업을 하나의 매개변수로 연결합니다.)
첫 번째는 간단합니다. y{*:}{_}
대신에 or를 사용하세요(Unix라고도 함).*
:
_
tr
두 번째는 더 복잡하고 다음을 사용합니다.뒤를 돌아보고 앞을 보아라필요한 구성 요소를 일치시킵니다. 이는 처리할 표현식이 \s+
바로 앞에 나와야 하며 파일 이름의 나머지 부분에서는 /
뒤따라오지 않아야 함을 의미합니다./
산출
rename(./ dkfjd L, ./dkfjd L)
rename(./aaa*, ./aaa_)
rename(./aaa*bbb, ./aaa_bbb)
rename(./ sdf.sdf, ./sdf.sdf)
rename(./aaa:bbb, ./aaa_bbb)