mv: 셀 스크립트에 해당 파일이나 디렉터리가 없습니다.

mv: 셀 스크립트에 해당 파일이나 디렉터리가 없습니다.

일부 파일을 한 폴더에서 다른 폴더로 이동하는 스크립트를 작성했지만 다음 오류가 발생합니다. 폴더 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과 동일합니다 .ba<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/*존재하는 정보입니다.

관련 정보