私はシェルスクリプトに初めて触れました。私は解決策を探しています。ディレクトリにファイルが追加された場合に備えて、私のディレクトリに10個のファイルを保持する必要があります。最も古いファイルだけを別のディレクトリに移動したいと思います。私のディレクトリ名はWorkで、他のディレクトリ名はRegular_archieveと指定しました。私はこれを試しました。
work = /home/balaji/work
regular_archieve = /home/balaji/regular_archieve
cd $work
for i in 'ls -t | sed -e '1,10d' | xargs -d '\n' rm -f'
do
mv $i $regular_archieve
done
if [ls -t | wc -1 > 10 | mv /home/balaji/regular-archieve]
then
echo "more than 10 n files"
fi
mv $(ls -t /home/balaji/work | sed -e '1,10d' | tail - 1) /home/balaji/regular_archieve
ただし、ファイルを別のディレクトリに移動することはできません。
このエラーが発生します。
mv: cannot stat 'file' : No such file or directory
答え1
ls
ターミナルで見るもの以外の用途での出力を使うのは良いことではありません。バラよりなぜいいえ解析ls
(および実行方法)?。代わりに、以下を使用してくださいfind
。
find /home/balaji/work/ -type f -printf '%C@\t%p\0' |
sort -z -k1,1 -r -n |
cut -z -f2 |
head -z -n 10 |
xargs -0r echo mv -t /home/balaji/regular_archive/
find
これには、GNUバージョンの、、、およびsort
(または少なくともNULレコード区切り文字オプションをサポートする他のバージョン)cut
が必要です。tail
xargs
-z
find
すべての一般ファイルに対して-printf '%C@\t%p\0'
最後に変更されたタイムスタンプ(%C@
1970-01-01 00:00:00以降の秒数)とファイル名()を一覧表示するために使用されます。フィールドは単一のタブ文字()で区切られ、各レコードは%p
NUL文字()で\t
区切られます。\0
- findの出力は、
-r
最初のフィールド()に対してのみファイルを数値逆順()でソートするためにsortにパイプされます。つまり、タイムスタンプに基づいています。-n
-k 1,1
- ソートの出力は、タイムスタンプフィールドを削除するためにパイプに接続されます(ソートが完了した後はもう必要ありません)。
- カットの出力は、
head
最初の10項目を得るためにパイプに接続されます。 - 最後に、head の出力が
xargs
runmv
コマンドにパイプされます。これはmvのGNU-t
拡張子を使用するため、ファイル名の前にターゲットディレクトリを指定できます。
実際、これはrunとecho mv
いうよりはrunmv
なので、pre-runです。echo
それがあなたが望むことをすることを確信したら、それを取除きなさい。
注:これは以下に適用されます。どの含まれている可能性がある奇妙で迷惑な文字(スペース、改行、シェルメタ文字など)に関係なく、ファイル名。また、このfile
コマンドには、検索基準を絞り込むために使用できる他の多くのオプションがあります。
以前のバージョンのGNU coreutils(<バージョン8.25など)を使用している場合cut
でも、オプションはありませんhead
。代わりにこれを使用できます。例えばtail
-z
awk
find /home/balaji/work/ -type f -printf '%C@\t%p\0' |
sort -z -k1,1 -r -n |
awk -F '\t' 'BEGIN {RS=ORS="\0"}; NR<=10 { $1=""; $0=$0; $1=$1 ; print }' |
xargs -0r echo mv -t /home/balaji/regular_archive/
perl
または、次のものを代わりに使用できますawk
。
perl -F'\t' -0lane 'if ($. <= 10) {delete $F[0]; print @F}'
答え2
私はあなたのコードで明白な構文エラーを無視し、最近修正された10個のファイルをディレクトリに保存したいと思います~/work
。また、zsh
利用可能なシェルがあるとします。
次のシェルスクリプトは、zsh
最後に変更された10個のファイルを除くすべてのファイルをからに~/work
移動します~/regular_archieve
。
#!/bin/zsh
mv -i $HOME/work/*(.om[11,-1]) $HOME/regular_archieve
スクリプト内の単一のコマンドは、最後に変更された10個のファイルをに保存し、~/work
残りのファイルを~/regular_archieve
。特定のワイルドカードパターンをmv
使用してこれを行いますzsh
。パターンは*(.om[11,-1])
移動する必要がある通常のファイルに展開されます(ディレクトリが一致しません)。om
修正タイムスタンプに基づいてファイルをソートし、このソートされたリスト[11,-1]
のファイル名11から最も古いファイルを選択します。出発点グローバル予選 .om[11,-1]
globが通常のファイルにのみ一致するようにします。
ディレクトリに何千ものファイルがある場合、「パラメータリストが多すぎます」というエラーが生成されることがあります。この場合、ループを使用してファイルを個別に移動します。
#!/bin/zsh
for pathname in $HOME/work/*(.om[11,-1]); do
mv -i $pathname $HOME/regular_archieve
done
答え3
この質問に対する別の答えを見つけました。使用するのに最適探す使用する代わりにコマンドエルエス注文する。これにより、最も古いファイルを見つけて使用できるようになります。MV別のディレクトリに移動するコマンドです。
mv $(find /home/balaji/work/ -type f -printf '%T+ %p\n' | sort | head -1) /home/balaji/regular_archieve
find
- ディレクトリ階層からファイルを検索します。
/home/balaji/work/
– 場所を検索します。
/home/balaji/regular_archieve/
- 目標位置。
type -f
- 一般ファイルのみを検索します。
-printf ‘%T+ %p\n’
- ファイルの最後の変更日時を+記号で区切って印刷します。 (例:2015-07-22+13:42:40.0000000000)。ここで、%pはファイル名を表します。 \n は改行を意味します。
sort | head -n 1
- sortコマンドは出力をソートし、出力をheadコマンドに送信して最も古いファイルを表示します。ここで、-n 1 は、最も古いファイルであるファイルが 1 つしかないことを意味します。