일부 파일을 한 폴더에서 다른 폴더로 이동하는 스크립트를 작성했지만 다음 오류가 발생합니다. 폴더 2개를 확인한 결과 1개 폴더에는 해당 파일이 있고 다른 폴더에는 해당 파일이 없는 것으로 나타났습니다. 그런데 모든 폴더에 표시되는 이유는 무엇입니까? "mv는 그러한 파일이나 디렉토리를 계산할 수 없습니다"
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/194.199.68.165_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/194.42.17.124_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/195.113.161.13_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/203.159.127.3_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/212.199.61.205_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/212.51.218.235_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/213.73.40.105_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/41.225.7.4_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/83.230.127.122_tcp.folder/data/*': No such file or directory
[esolve@kitty tcp_50x50]$ ls /home/wgong/project/capture/tcp_50x50/dest_folder/194.199.68.165_tcp.folder/
[esolve@kitty tcp_50x50]$ ls /home/wgong/project/capture/tcp_50x50/dest_folder/203.159.127.3_tcp.folder/data/
129.88.70.226 132.187.230.1 138.96.116.22 155.185.54.250 192.38.109.144 193.136.227.163 193.175.135.61 195.113.161.13 83.230.127.122
130.104.72.200 132.227.62.122 147.83.29.232 156.17.10.52 192.42.43.22 193.137.173.218 193.205.215.74 212.199.61.205
131.130.69.164 132.252.152.194 148.81.140.193 157.181.175.249 192.43.193.71 193.144.21.131 193.226.19.30 212.51.218.235
131.188.44.102 134.151.255.180 152.66.245.162 160.78.253.31 193.1.170.136 193.145.46.243 194.199.68.165 213.73.40.105
131.254.208.10 138.48.3.203 152.81.47.4 192.114.4.3 193.136.166.56 193.166.160.98 194.42.17.124 41.225.7.4
스크립트는 다음과 같습니다
list=`ls dest_folder`
cd dest_folder
cwd=`pwd`
for folder in $list;do
mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
done
나는 그것을 안으로 달렸다 /home/esolve/project/capture/tcp_50x50/
.
답변1
mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
거기에 있는 따옴표( ) '
는 쉘이 와일드카드를 사용하는 것을 방지합니다. 명령에 그대로 전달 되는데 *
표시된 디렉토리에서 mv
호출된 파일을 찾을 수 없기 때문에 실패합니다.*
다음으로 변경하세요.
mv "${cwd}/${folder}/data"/* "${cwd}/${folder}"
(디렉터리 이름에 공백이 포함된 경우 문제를 방지하기 위해 큰따옴표를 사용하십시오. *
따옴표 바깥쪽에.)
그러나 빈 디렉터리에 대해서는 여전히 오류가 발생합니다. (같은 이유: 파일이 패턴과 일치하는 항목을 찾지 못하면 패턴 자체를 명령에 인수로 전달합니다.)
답변2
코드에 몇 가지 문제가 있습니다.
list=`ls dest_folder`
ls
줄 바꿈 없이 출력을 에 저장합니다 $list
. ls
줄 바꿈으로 구분된 파일 이름 목록을 출력합니다. newline
파일 이름의 모든 문자로 유효하므로 출력을 안정적으로 사용할 수 없습니다. 예를 들어, ls
다음을 포함하는 디렉터리의 출력은 이라는 파일이 포함된 디렉터리의 출력 a
과 동일합니다 .b
a<newline>b
cd dest_folder
명령이 실패했는지 확인하지 않았습니다. 일반적으로 명령의 종료 상태를 확인해야 하지만 이는 특히 의 경우에 해당됩니다 cd
. 왜냐하면 나머지 명령에서는 사용자가 새 디렉토리에 있다고 가정하고 그렇지 않은 경우 심각한 결과를 초래할 수 있기 때문입니다.
cwd=`pwd`
POSIX 쉘은 이미 (a) 변수의 현재 디렉토리에 대한 경로를 유지하고 $PWD
있으므로 여기서는 이를 사용할 필요가 없습니다
(특히 일반적인 경우 명령 대체가 경로에서 후행 개행 문자를 제거하므로). 또한 pwd
mv
상대 경로가 허용되므로 절대 경로를 작성할 필요가 없습니다.
for folder in $list;do
따옴표가 없는 변수는 다음과 같습니다.분할+전역셸의 연산자. 즉, 변수의 내용이 분할되고( $IFS
공백 구분 기호에 대한 특수 규칙에 언급된 구분 기호에 따라) 해당 분할로 인해 발생하는 각 요소의 와일드카드를 찾아서 일치하는 파일 목록으로 확장할 수 있습니다.
여기서는 분할이 필요하지만 개행에서만 가능하고 와일드카드를 원하지 않으므로 비활성화해야 합니다.
IFS='
'; set -f
for folder in $list
mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
마찬가지로 변수를 따옴표로 묶지 않은 상태로 두는 것은분할+전역운영자. 여기서는 둘 다 원하지 않으므로 변수를 참조해야 합니다.
*
앞에서 언급했듯이 와일드카드는 따옴표가 없는 경우에만 확장되므로 따옴표에서 제거 해야 합니다 . 이전에 를 사용하여 와일드카드를 비활성화한 경우 이 명령을 호출하기 전에 이를 복원 set -f
해야 합니다 .set +f
더 나은 작성 방법은 다음과 같습니다.
cd dest_folder &&
for folder in */;do
mv -- "${folder}data/"* "$folder"
done
그러나 몇 가지 주의 사항이 있습니다.
- 이렇게 하면 숨겨진 폴더가 제외되고
data
폴더에서 숨겨진 파일이 이동되지 않습니다. - 이 과정에서 덮어쓴 파일은 확인하지 않습니다(해당
-i
옵션을 추가해야 할 수도 있음mv
). - 을 사용하여
*/
우리는 루프를 돌립니다.목차단, 디렉토리에 대한 심볼릭 링크도 포함합니다. 원하지 않는 경우[ -L "${folder%/}" ] && continue
루프 내부에 하나를 추가해야 합니다. - 숨겨지지 않은 폴더가 없으면
*/
자체적으로 확장되므로mv
이라는 파일을 찾을 수 없다는 오류 가*/data/*
발생합니다. 마찬가지로 폴더에 숨겨지지 않은 파일이 없으면that-folder/data/*
존재하는 정보입니다.