디렉토리 내에 /home/username/data
파일과 디렉토리가 모두 있습니다. 이 파일 이름 중 일부는 .txt
다음 으로 끝납니다.텍스트 파일), 다른 사람들은 그렇지 않습니다. 하위 디렉터리에서도 같은 일이 발생합니다.
하위 디렉터리 중 하나 other_files
(전체 경로는 /home/username/data/other_files/
)를 호출합니다.
시작하지 않는 모든 것을 옮기고 싶어.txt
루트에 /home/username/data
도착하다 other_files
.
루프를 사용하여 이 작업을 수행할 수 있지만 이는 내가 원하는 것이 아닙니다. 명령과 파이프를 사용하고 싶습니다. 나는 그것이 쉽다고 확신합니다. 나는 그것을 보지 못합니다. , , 의 조합이 트릭을 수행 mv
해야 하는데 어떻게 해야 하는지 잘 모르겠습니다.find
grep
xargs
그래서 저는 텍스트 파일을 일치시키려고 노력해 왔습니다(그리고 그 파일을 제외한 모든 것을 일치시키는 방법을 알아내려고 노력했습니다). 다음은 현재 디렉터리가 이라고 가정합니다 /home/username/data
.
먼저 선택했지만 find . | grep -E "*\.txt"
하위 디렉터리의 파일을 포함한 모든 텍스트 파일과 일치합니다.
그래서 find . | grep -E "\./*\.txt"
같은 매치가 나올지 알아보고 목표를 향해 노력했지만 아무것도 매치되지 않았고 거기서 막혔습니다.
질문 시작 부분에 설명한 내용을 어떻게 수행합니까?
답변1
간단한 쉘 루프 변형(in bash
):
shopt -s extglob dotglob nullglob
for pathname in ~username/data/!(*.txt); do
! test -d "$pathname" && mv "$pathname" ~username/data/other_files
done
첫 번째 줄에 설정된 셸 옵션을 사용하면 bash
셸에서 확장된 globbing 패턴을 활성화합니다( . !(*.txt)
로 끝나지 않는.txt
모든 이름과 일치).
루프 본문은 디렉터리(또는 디렉터리에 대한 심볼릭 링크)의 모든 항목을 건너뛰고 다른 모든 항목을 지정된 디렉터리로 이동합니다.
find
GNU에 해당하는 기능 mv
(심볼릭 링크가 있는 경우 디렉토리로 이동하고 mv
동시에 많은 파일을 호출하지만 이것이 유일한 차이점입니다):
find ~username/data -maxdepth 1 ! -type d ! -name '*.txt' \
-exec mv -t ~username/data/other_files {} +
관련된:
답변2
find /home/username/data -maxdepth 1 -type f ! -name '*.txt' -exec mv {} /home/username/data/other_files/ \;
- 최고 이사의 최대 심도 제한
- type은 디렉터리가 아닌 파일만 찾을 수 있도록 보장합니다.
답변3
이 코드는 ".txt"로 끝나지 않는 모든 파일을 대상 폴더로 이동해야 하지만, 다른 경로에 동일한 이름의 파일이 있으면 오류가 발생합니다.
find /home/username/data ! -name "*.txt" -type f -maxdepth 1 -exec mv {} /home/username/data/other_files/ \;
답변4
다음 줄은 *.txt
현재 디렉터리에서 경로가 아닌 모든 파일과 숨겨진 파일을 찾아 새 경로로 이동합니다.
ls -1p | grep -v "^.*\.txt$" | grep -v ".*/$" | xargs mv -vt newpath
다음은 동일하지만 숨겨진 파일도 이동합니다.
ls -1ap | grep -v "^.*\.txt$" | grep -v ".*/$" | xargs mv -vt newpath
명령줄에서는 디렉터리를 재귀적으로 검색하지 않으며 디렉터리를 이동하지도 않습니다.
파일 이름에 공백이 포함되어 있으면 다음을 사용할 수 있습니다.
ls -1ap | grep -v "^.*\.txt$" | grep -v ".*/$" | xargs -d'\n' printf "\"%s\"\n" | xargs mv -vt newpath