mv : stat script stat 스크립트에 해당 파일이나 디렉토리가 없습니다


16

하나의 폴더에서 다른 폴더로 일부 파일을 이동하는 스크립트를 작성했지만 다음 오류가 발생했습니다 .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
스크립트의 관련 부분을 보여주십시오.
Mat

질문을 업데이트하고 스크립트를 추가했습니다. 감사합니다!
misteryes

당신은 추가해야합니까 -r받는 사람 mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}?
ProfessionalAmateur

-rmv
misteryes

답변:


25
mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}

따옴표 ( ')는 쉘이 글 로빙을 수행하지 못하게합니다. 은 *받는 문자 그대로 전달되는 mv것이라는 파일을 찾을 수 없기 때문에 실패 명령, *지시 된 디렉토리에 있습니다.

이것을 다음으로 변경하십시오.

mv "${cwd}/${folder}/data"/* "${cwd}/${folder}"

(따옴표없이 공백이있는 디렉토리 이름이있는 경우 문제를 방지하기 위해 큰 *따옴표. 따옴표 외부)

빈 디렉토리에 대해서는 여전히 오류가 발생합니다. (같은 종류의 이유 : 파일이 패턴과 일치하지 않으면 패턴 자체를 명령의 인수로 전달합니다.)


큰 따옴표는 의미가 있지만 *따옴표 외부에 배치해야하는 이유는 무엇입니까?
Sibbs Gambling

확장하려면 @SibbsGambling
Mat

8

코드에는 몇 가지 문제가 있습니다.

list=`ls dest_folder`

ls후행 줄 바꿈 문자없이 의 출력을에 저장합니다 $list. ls줄 바꿈 문자로 구분 된 파일 이름 목록을 출력합니다. newline파일 이름에서와 같이 유효한 문자이므로 출력을 안정적으로 사용할 수 없습니다. 예를 들어, 라는 파일이 하나 ls포함 된 디렉토리 의 출력 ab동일하고 동일한 디렉토리 의 출력입니다 a<newline>b.

 cd dest_folder

해당 명령의 실패를 점검하지 않습니다. 일반적으로 명령의 종료 상태를 확인해야하지만 cd, 나머지 명령은 사용자가 새 디렉토리에 있다고 가정하고 그렇지 않은 경우 큰 결과를 초래할 수 있기 때문에 특히 그렇습니다 .

cwd=`pwd`

POSIX 쉘은 이미 $PWD변수 의 현재 디렉토리에 대한 (하나의) 경로를 유지 하므로 pwd여기 에서 사용할 필요가 없습니다 (특히 명령 대체가 경로에서 후행 줄 바꿈 문자를 제거하기 때문에 일반적인 경우). 또한 mv상대 경로를 허용하므로 절대 경로를 만들 필요가 없습니다.

for folder in $list;do

따옴표없는 변수 는 쉘에서 split + glob 연산자입니다. 즉, 변수의 내용이 분할됩니다 ($IFS 공백에 대한 특수 규칙으로 ) 분리의 결과로 나오는 각 요소는 와일드 카드 문자를 찾아서 일치하는 파일 목록으로 확장 될 수 있습니다.

여기서는 분할을 원하지만 개행 문자에서만 가능하며 글 로빙을 원하지 않으므로 비활성화해야합니다.

 IFS='
 '; set -f
 for folder in $list
   mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}

다시 말하지만 변수를 따옴표로 묶지 않은 것은 split + glob 연산자입니다. 여기서는 둘 다 원하지 않으므로 해당 변수를 인용해야합니다.

이미 언급했듯이 와일드 카드는 *따옴표로 묶지 않은 경우에만 확장되므로 따옴표에서 제외 해야 합니다. 로 이전에 글 로빙을 비활성화 한 경우 해당 명령을 호출하기 전에 글 로빙 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/*이 없으면 존재하지 않는 오류 메시지가 표시 됩니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.