명령 도움말 찾기: Linux에서 공백(또는 공백)으로 시작하는 파일 또는 폴더 찾기

명령 도움말 찾기: Linux에서 공백(또는 공백)으로 시작하는 파일 또는 폴더 찾기

다음 중 하나를 검색하는 방법:

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만족스러우면 시험 실행에서 제거 )

관련 정보