다음 중 하나를 검색하는 방법:
Linux에서 공백으로 시작하는 폴더를 찾은 다음 폴더가 문자나 숫자로 시작할 수 있도록 모든 시작 공백을 제거하시겠습니까?
Linux에서 공백으로 시작하는 파일을 찾은 다음 파일이 문자나 숫자로 시작할 수 있도록 모든 선행 공백을 제거하시겠습니까?
답변1
find . -depth -name ' *' -exec sh -c '
for pathname do
newname=${pathname##*/}
newname=${newname#"${newname%%[! ]*}"}
newpathname=${pathname%/*}/$newname
if [ -z "$newname" ] || [ -e "$newpathname" ]; then
continue
fi
mv -v "$pathname" "$newpathname"
done' sh {} +
위의 코드는 이름이 하나 이상의 공백 문자로 시작하는 현재 디렉터리 안이나 아래의 모든 파일이나 디렉터리를 찾습니다. 내용이 아직 처리되지 않은 디렉터리의 이름을 바꾸는 것을 방지하기 위해 깊이 우선 순서로 이 작업을 수행합니다. -depth
그렇지 않으면 디렉터리 이름을 바꾸면 이름 find
이 바뀌었기 때문에 나중에 찾을 수 없게 됩니다.
공백으로 시작하는 이름 배치에 대해 짧은 인라인 쉘 스크립트를 호출하십시오. 이 스크립트는 주어진 경로 이름을 반복하고 먼저 현재 경로 이름 끝에 있는 실제 이름을 변수로 추출합니다 newname
. 이는 표준 매개변수 대체를 사용하여 ${pathname##*/}
문자열의 마지막 모든 항목(가장 긴 접두사 일치)을 제거하고 최종 경로 이름 구성 요소를 남겨 두는 방식으로 이를 수행합니다. 이는 기본적으로 이 예와 동일합니다./
*/
"$(basename "$pathname")"
그런 다음 문자열 시작 부분에 존재하는 것으로 보장되는 공백을 잘라야 합니다 $newname
. 이를 위해 먼저 공백 ${newname%%[! ]*}
(가장 긴 접미사 일치, 즉 공백이 아닌 첫 번째 문자부터 시작)을 제외한 모든 항목을 제거한 다음 [! ]*
문자열의 시작 부분에서 결과를 제거합니다.$newname
${newname#"${newname%%[! ]*}"}
명령의 대상 경로는 mv
슬래시로 연결된 디렉터리 경로와 새 이름 ie로 구성되며 이는 기본적으로 ie와 동일합니다.$pathname
${pathname%/*}/$newname
"$(dirname "$pathname")/$newname"
이 코드는 이름 충돌을 감지하고 잠재적으로 충돌할 수 있는 이름의 처리를 자동으로 건너뜁니다. 또한 빈 문자열로 축소되는 이름도 건너뜁니다. 이것이 if
이전 진술이 mv
하는 일입니다. 사용자가 이러한 이름을 알 수 있도록 하려면 이전에 수행하십시오 continue
.
테스트는 다음에서 실행됩니다.복사백업 데이터.
위 코드를 테스트 실행해 보세요.
$ tree -Q
"."
|-- " dir0"
| |-- " o dir1"
| | |-- " otherfile"
| | `-- "dir2"
| | |-- " dir3"
| | `-- " moar"
| `-- "file"
`-- "script"
4 directories, 4 files
$ sh script
./ dir0/ o dir1/dir2/ moar -> ./ dir0/ o dir1/dir2/moar
./ dir0/ o dir1/dir2/ dir3 -> ./ dir0/ o dir1/dir2/dir3
./ dir0/ o dir1/ otherfile -> ./ dir0/ o dir1/otherfile
./ dir0/ o dir1 -> ./ dir0/o dir1
./ dir0 -> ./dir0
디렉터리 계층 구조의 맨 아래에서 어떻게 시작되는지 확인하세요. 먼저 이름을 바꾸려고 하면 dir0
나중에 다른 디렉터리와 파일의 이름을 바꾸기 위해 입력할 수 없습니다.
$ tree -Q
"."
|-- "dir0"
| |-- "file"
| `-- "o dir1"
| |-- "dir2"
| | |-- "dir3"
| | `-- "moar"
| `-- "otherfile"
`-- "script"
4 directories, 4 files
답변2
스크립트는 공백으로 시작하는 파일을 찾고 실행할 명령을 인쇄합니다. 이 스크립트가 제대로 작동하려면 실제 mv 명령의 주석 처리를 제거해야 합니다. 원하는 디렉터리에서 실행되어야 합니다. 현재 디렉터리 내의 모든 파일과 폴더는 변경되지만 현재 디렉터리 내의 하위 디렉터리는 변경되지 않습니다. " 123
" 및 " " 이라는 두 개의 파일이 있을 수 있으며 123
지시어는 해당 파일의 이름을 동일한 내용으로 바꿉니다.
되돌릴 수 없습니다. mv에 -i를 추가했지만 사용자가 지정하지 않는 한 파일을 덮어쓰지 않습니다. 이 스크립트를 실행하기 전에 시스템이 충돌할 경우를 대비해 백업하는 것을 포함하여 세심한 주의를 기울일 것입니다.
#!/bin/bash
# tell read not to word split
IFS=
# find all files starting with space
find ./ -maxdepth 1 -name " *" -print0 | \
while read -d '' a
do
# new filename without leading spaces
nm=$( echo "$a" | sed 's/^.\/ */.\//')
# use -i to not overwrite files
echo mv -i \"$a\" \"$nm\"
# uncomment the next line to do the actual move
#mv -i "$a" "$nm"
done
답변3
그리고 zsh
:
autoload -Uz zmv
zmv -n '(**/) ##(*)(#qD/)' '$1$2'
( -n
만족스러우면 시험 실행에서 제거 )