mv:シェルスクリプトにそのようなファイルまたはディレクトリがありません。


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
スクリプトの関連部分を示してください。
マット

質問を更新し、スクリプトを追加しました、ありがとう!
ミステリー

あなたが追加する必要がありますか-rmv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
ProfessionalAmateur

-rオプションはありませんmv
ミステリー

回答:


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

引用符(')は、シェルがグロビングを実行するのを防ぎます。*文字通り渡されているmvことが呼ばれるファイルが見つからないので、失敗したコマンドを、*示されたディレクトリにします。

これを次のように変更します。

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

(二重引用符は、スペースを含むディレクトリ名がある場合に問題を防ぐために使用*します。引用符の外側。)

ただし、空のディレクトリのエラーは引き続き表示されます。(同様の理由:ファイルがパターンに一致するものを見つけられない場合、コマンドへの引数としてパターン自体を渡します。)


二重引用符は理にかなっていますが、なぜ*引用符の外側に置く必要があるのですか?
シブスギャンブル

拡張したい場合は、@ SibbsGamblingの外でそれが必要です
マット

8

コードにはいくつかの問題があります。

list=`ls dest_folder`

の出力lsを、末尾の改行文字なしでに保存しています$listls改行文字で区切られたファイル名のリストを出力します。newlineファイル名に含まれる文字と同じように有効な文字であるため、出力を確実に使用することはできません。例えばls含まれているディレクトリ用の出力ab呼ばれる一つのファイルを含むディレクトリのためのものと同じですa<newline>b

 cd dest_folder

そのコマンドの失敗を確認していません。一般に、コマンドの終了ステータスを確認する必要がありますが、これは特に当てはまりcdます。残りのコマンドでは、新しいディレクトリにいると想定しているため、そうでない場合は劇的な結果を招く可能性があります。

cwd=`pwd`

POSIXシェルは、$PWD変数内の現在のディレクトリへの(1つの)パスを既に保持しているため、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 -fset +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.