web-dev-qa-db-ja.com

最新のファイルをあるディレクトリから別のディレクトリにコピーするにはどうすればよいですか?

ディレクトリに3つのZipファイルがあります。最新バージョンをバックアップディレクトリにコピーしたい。

私のコードは.shおよびその他のファイル、ただし.Zip。他に何かしなければならないことはありますか?

cp -p `ls -tr1 /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Original/| tail -1` /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Backup1/ 

それは言う:cp: website3.Zip: No such file or directory

5
smj2393

これを実行してください:

cp -p "`ls -dtr1 /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Original/* | tail -1`" /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Backup1/

ここでは、絶対パスを取得するために-dオプションos lsを追加しています。

コマンドでは、lsは絶対パスを返さないため、ファイルをコピーするにはソースディレクトリから実行する必要があります。ファイルがない他のディレクトリから実行したため、エラーNo such file or directoryが表示されます。

また、パスにスペースが含まれているため、ls -dtr1 /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Original/* | tail -1を引用符で囲んで、Shellがその出力でWord分割を行わないようにする必要があります。

7
heemayl

他の人がすでに気づいているように、あなたのアプローチには2つの問題があります。それらは、.Zipファイルと.shファイルには関係なく、ファイルの名前と場所に関係します。

コマンド置換を二重引用符で囲む必要があります。それ以外の場合は、空白文字で中断します。詳細については、 なぜシェルスクリプトが空白やその他の特殊文字を詰まらせるのですか? を参照してください。

さらに、lsコマンドは、ディレクトリ部分なしで、ファイルのベース名のみを出力します。したがって、cpはベース名のみを参照し、別のディレクトリにあるファイルを意味していることを知りません。これを修正する1つの方法は、最初に目的のディレクトリに切り替えることです。

cd /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Original/
cp -p "`ls -tr | tail -1`" ../Backup1/ 

最新のZipファイルだけが必要で、最新のファイルが何も必要ない場合:

cd /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Original/
cp -p "`ls -dtr *.Zip | tail -1`" ../Backup1/ 

ディレクトリが空の場合、または現在のロケールでは印刷できない改行または文字を含むファイル名がある場合、これは奇妙なエラーメッセージで失敗しますが、これらは比較的まれな状況です。

オプション-dは、名前が*.Zipと一致するサブディレクトリがある場合の安全性を少し高めます。オプション-1は必要ありません。その効果は、lsの出力が別のコマンドにリダイレクトされるときに自動的に行われます。

または、 zsh を使用することもできます。これにより、 glob qualifiers のおかげで、これを簡単に行うことができます。

cp -p /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Original/*(om[1]) /Users/Me/Documents/Coffi\ Work/FTP\ Backup\ Shell\ Script/Backup1/

それは、cpを実行する場所に依存するためです。あなたの例では、ls -tr1 /Users/Me/Whateverwebsite3.Zipのみを返します。 /tmpからcpを実行すると、ファイル/tmp/website3.Zipが検索されます。

lsにフルパスを表示させるには、ワイルドカード*を使用する必要があります。必要に応じて、lsにすべてのサブディレクトリの内容をリストさせないように-dオプションを指定すると便利な場合があります。

$ ls -tr1d /Users/Me/Whatever
...
website3.Zip

$ ls -tr1d /Users/Me/Whatever/*
...
/Users/Me/Whatever/website3.Zip

ただし、最後に変更されたエントリがディレクトリの場合は注意してください。この場合、-Rオプションを省略した場合、cpはそれをコピーしません。

ファイルに常に.Zip拡張子が付いている場合は、次のことを検討してください。

$ ls -tr1d /Users/Me/Whatever/*.Zip

ディレクトリが空の場合もエラーが発生することがあります。次のようなスクリプトを作成してみませんか。

#!/bin/bash

MY_DIR="/Users/Me/Documents/Coffi Work/FTP Backup Shell Script/Original/"
DEST="/Users/Me/Documents/Coffi Work/FTP Backup Shell Script/Backup1/"
FILEEXT="Zip"

NEWEST=`ls -tr1d "${MY_DIR}/"*.${FILEEXT} 2>/dev/null | tail -1`

if [ -z "${NEWEST}" ] ; then
    echo "No file to copy"
    exit 1
Elif [ -d "${NEWEST}" ] ; then
    echo "The most recent entry is a directory"
    exit 1
else
    echo "Copying ${NEWEST}"
    cp -p "${NEWEST}" "${DEST}"
fi
1
apaul