私のフォルダには、次のファイルがいくつかあります。
ContractAdjustments.CHRS201804202144.txt
ContractAdjustments.CHRS201804212144.txt
ContractAdjustments.CHRS201804222144.txt
ContractAdjustments.CHRS201804232144.txt
最新のファイルだけをアーカイブし、残りはアーカイブの場所に移動したいと思います。次のスクリプトを使用していますが、エラーが発生します。
$ find -maxdepth 1 -type f -iname 'ContractAdjustments.*.TXT' -printf '%T@|%p\n' | sort -r -n | tail -n +2 | cut -d'|' -f2 | xargs -i mv {} ARCHV
答え1
#!/bin/sh
mkdir -p ARCHIVE || exit 1
newest=
for file in ContractAdjustments.*.txt; do
if [ -f "$file" ]; then
if [ -z "$newest" ]; then
# this is the first file, initialize "newest"
newest=$file
elif [ "$file" -nt "$newest" ]; then
# file is newer than "newest",
# archive "newest" and set new newest file
mv -i "$newest" ARCHIVE
newest="$file"
else
# file is older, archive it
mv -i "$file" ARCHIVE
fi
fi
done
if [ -n "$newest" ]; then
printf 'Done. Newest file = %s\n' "$newest"
else
echo 'No files found'
fi
テストが組み込みコマンドで実装されると、/bin/sh
スクリプトは最新のファイルを変更せずにすべての古いファイルをフォルダに移動します。-nt
[
ARCHIVE
これは、指定されたパターンに一致するファイル名を繰り返し、各ファイルに対してこれまでに見つかった最新のファイルに対してタイムスタンプをテストし、最新のファイルか古いファイルであるかに応じてファイルを移動する方法で行われます。
スクリプトは、ファイル名にスペース文字などを保持する操作を正しく処理します。この特別なケースでは問題にならないかもしれませんが、通常、Unixファイル名にはファイル名のワイルドカードだけでなく、スペースや挿入された改行も含めることができます。
立ち寄りたいならファイル名ファイルのタイムスタンプに基づいて並べ替えるのではなく、次の手順を実行します。
#!/bin/sh
mkdir -p ARCHIVE || exit 1
set -- ContractAdjustments.*.txt
while [ "$#" -gt 1 ]; do
mv -i "$1" ARCHIVE
shift
done
printf 'Done. Newest file = %s\n' "$1"
これは、位置引数(など)を与えられたパターンに一致するファイルのリスト$1
に設定します。$2
次に、リストにまだ複数のファイルがある場合は、リストの最初のファイルをディレクトリに移動しARCHIVE
てリストから削除します。リストの最後のファイルは、ファイル名に基づいて最後にランク付けされたファイルです(そのファイルは現在の場所に残ります)。
答え2
簡単な方法は次のとおりです。
mv `ls -t ContractAdjustments.*.txt | awk '{ iteration+=1; if (iteration > 1) { print } } ' ` ARCHV
もちろん、これはエッジ条件(たとえば、ディレクトリにファイルが1つしかない場合)でエラーを生成しますが、常に機能します。
答え3
最初のファイルを除く各ファイルのリストを変数に入れ、そのファイルに対して for ループを実行します。
listinmemory=`ls -alht | tail -n +5 | awk '{print $9}'`; for each in $listinmemory; do mv $each /path/to/directory; done
ls -alht
何も実行したくない4行が一覧表示されます。
total 123K
drwxr-xr-x. 5 user user 1.0K Jun 27 09:20 .
drwx------. 13 user user 2.0K Jun 27 10:36 ..
-rw-rw-r--. 1 user user 3.0K Jun 6 18:29 file1
最新のファイルと3行 - それから実行したすべてのファイルなので、tail -n +5
最初の4行をスキップして見つけたmv $each /path/to/directory
すべてのファイルを実行します!
答え4
ls
あなたの場合、cd
ディレクトリに解析して次のことを行うのは良い考えではありません。
for CA in $(find . -maxdepth 1 -type f -name ContractAdjustments\*.txt | head --lines=-1); do mv $CA /path/to/archive/; done
コマンド置換を含むループを使用して、ディレクトリfor
で指定された形式で始まるすべてのファイルを見つけ、ContractAdjustments*.txt
2番目のオクテットの日付に基づいて最も古いものから最新のものまでリストします。次に、パイプを介して--head --lines=-1
最後の行(最新のファイル)を除くすべての項目を印刷し、その値を変数CA
(ContractAdjustmentsの場合)に渡します。最後に、最新のファイルを除くすべてのファイルをアーカイブの場所に移動するdo
ために使用されます。mv