디렉토리에는 다음 이름의 파일이 있습니다.
01.txt 02.txt 03.txt
동일한 디렉터리의 폴더 이름은 다음과 같습니다.
01.abc 02.def 03.ghi
파일을 폴더에 하나씩 복사하는 명령이 필요합니다. 즉, 01.txt
is in 01.abc
, 02.txt
is in 02.def
및 03.txt
is in 입니다 03.ghi
. 이 명령은 폴더 이름을 고려하지 않고 폴더를 위에서 아래로 파일로 채워야 합니다(폴더당 하나의 파일).
매우 감사합니다!
편집 1:
코드를 변경했습니다파일을 여러 폴더로 이동[닫기]다음과 같이:
#!/bin/bash
LISTFILESCMD='ls *.txt'
FQUANTITY=1
FOLDERLIST=`seq -w 1 3`
for FOLDER in $FOLDERLIST; do mv `$LISTFILESCMD | head -n $FQUANTITY` $FOLDER; done
결과적으로 이 3개의 파일은 세 번째 폴더에 위치하게 됩니다.
편집 2:
아니요, FQUANTITY=3이면 파일이 첫 번째 폴더로 이동합니다.
위 스크립트는 FQUANTITY=1일 때 작동합니다. 단, 파일명이나 폴더명에 공백이 포함되어 있으면 제대로 동작하지 않습니다.
파일 이름의 공백에도 작동하는 두 번째 스크립트를 만들었지만 파일 이름에 점이 포함된 경우에만 해당하고 폴더 이름에 공백이 포함된 경우 이 스크립트는 작동하지 않습니다. 폴더 이름에 공백이 있거나 파일 이름에 점이 없는 경우에도 작동하도록 하는 방법이 궁금합니다.
#!/bin/bash
array1=(*/) # folder
array2=(*.*) # file
for ((i=0;i<${#array2[@]};++i)); do
mv "${array2[i]}" "${array1[i]}"
done
감사해요!
답변1
결과적으로 이 3개의 파일은 세 번째 폴더에 위치하게 됩니다.
첫 번째 폴더를 말하는 건가요? 총 3개의 파일만 있는 경우 fquantity=3을 선택하는 이유는 무엇입니까? 폴더당 파일 개수입니다!
for 루프를 테스트했는데 지금까지 작동합니다. 디렉터리 전체에 파일을 균등하게 배포하려면 올바른 "양"을 선택해야 합니다.
귀하의 Q는 귀하가 제공한 파일 이름과 수량으로 인해 실제로 이해하기가 약간 어렵습니다. 그리고: 01.txt는 01.abc에 속하지만 "이름은 고려하면 안 됩니다".
17개 폴더로 이동해야 하는 3000개의 파일이 있다고 가정해 보겠습니다. 또는 x개 폴더, 각 폴더의 최대 개수는 다음과 같습니다. 파일이 200개? 이것은 첫 번째 단계, 간단한 수학 및 카운터가 있는 루프가 될 것입니다.
다음은 "강건성"(공백)과 성능, 그리고 "프로그램"을 단순화하기 위해 표준 명령을 사용하는 방법에 대한 질문입니다.
귀하의 예:
for FOLDER in $FOLDERLIST; do mv `$LISTFILESCMD | head -n $FQUANTITY` $FOLDER; done
파일 목록이 필요하지 않기 때문에 어떤 면에서는 우아합니다.남은(이동되지 않은) 파일. 그리고 하나의 큰 명령으로 각 폴더를 한 번만 채우면 되기 때문에 충분히 빨라야 합니다 mv
.
(fquantity)에 대한 올바른 매개변수를 선택함으로써 head
필요에 따라 7개의 파일을 3개의 디렉터리로 이동할 수 있습니다. --- 저는 3-3-1을 원한다고 생각했습니다. 그러나 수량 "7"을 선택하면 첫 번째 디렉터리에 있는 7개 파일을 모두 가져옵니다. "1"을 사용하면 1-1-1과 이동되지 않은 4개의 파일이 생성됩니다. 이상적인 상황은 3-2-2입니다. 따라서 관련된 수학은 그렇게 간단하지 않을 수도 있습니다.
그러나 공백이 있는 파일 이름은 이동되지 않으며 mv
작성자는 놀란 듯 다음과 같이 말했습니다.아 공간 문제인가봐요.
답변2
배열 솔루션은 공백이 포함된 파일에도 작동해야 합니다.했다확장명을 올바르게 인용하세요. 그러나 대시로 시작하는 파일 이름에 문제가 발생할 수 있지만 mv -- file dir/
이를 사용하여 이를 방지할 수 있습니다(또는 대신 ./
와일드카드 앞에 배치 등)../*
*
파일을 선택하는 것에 관해서는 Bash에서 직접 수행할 수 있는 방법은 없다고 생각합니다(그러나 zsh에서는 수행할 수 있습니다). 하지만 모든 목록을 선택하고 그 목록에서 일반 파일을 필터링할 수 있습니다.
#!/bin/bash
dirs=(*/) # directories
tmp=(*) # everything
files=() # files
for f in "${tmp[@]}"; do
if [ -f "$f" ]; then
files+=("$f")
fi
done
for ((i=0 ; i < ${#dirs[@]} ; ++i)); do
mv -- "${files[i]}" "${dirs[i]}"
done