web-dev-qa-db-ja.com

ディレクトリ内の最後の8ファイルのみを別のディレクトリに移動する

最後の8つのファイルをDocumentsディレクトリから別のディレクトリに移動しようとしていますが、それらを1つずつ特定のディレクトリに移動したくありません。 tailコマンドの代わりにファイルを移動することはできますが、ファイルではなくディレクトリに移動できますか?つまり、tail -8 ./Documents | mv ./Anotherdirectorymv tail -8 ./Documents ./Anotherdirectoryのようなものを使用したいのです。

実際、最後の8つのファイル(lsにリストされている)を(各名前を入力せずに)他のディレクトリにすばやく移動できる賢い方法を探しています。助言がありますか?

7
Sandra Ross

forを使用すると、ファイルを順序どおりにループし、findまたはlsの出力の解析を回避して、スペースやその他の特殊文字の問題を回避できます。ファイル名。これを改善してくれた@muruに感謝します:)

i=0; j=$(stat ~/Documents/* --printf "%i\n" | wc -l); for k in ~/Documents/*; do if (( (j - ++i) < 8 )); then echo mv -v "$k" ~/AnotherDirectory; fi; done 

最初にechoでテストしてから、echoを削除して、実際にファイルを移動します。

スクリプトとして:

#!/bin/bash
i=0
j=$(stat ~/Documents/* --printf "%i\n" | wc -l )
for k in ~/Documents/*; do
  if (( (j - ++i) < 8 )); then
    echo mv -v -- "$k" ~/AnotherDirectory
  fi
done

もう一度、テスト後にechoを削除して、実際にファイルを移動します

説明

7
Zanna

コマンド置換を使用して、このようなことを行うことができます。 Bashの場合:

mv $(ls -d [sort options] source/* | tail -n8) destination

$(command)は、囲まれているものをすべて実行し、テキスト出力を外部コマンドに置き換えます。このlsコマンドは、指定したフラグに従って1行に1つずつソートされたソースディレクトリ内の各ファイルへのパスを出力します。したがって、tailは最後の数個だけを取得できます。したがって、上記は

mv source/file1 source/file2 source/file3 ... source/file8 destination

ls -d [sort options] source/* | tail -n8を実行するだけで、コピーするファイルを確認できます。

lsの出力の順序付け方法とファイルの名前付けに応じて、mv source/name_* destinationのバリアントを使用して "name_"で始まるすべてをコピーするだけで、探しているものをより簡単に実行できる宛先ディレクトリ。

EDIT:ファイル名にスペースが含まれている場合、上記は中断します。これに対処するより複雑な代替案は

ls -d1 [sort options] source/* | tail -n8 | tr '\n' '\0' | xargs --null mv -t destination

ただし、ls出力の解析を使用して、アルファベット順ではない任意の順序で並べ替えを取得します。

3
t-mager

t-magerの提案と同様に、lsソートオプションを使用して、最後の8つのファイルをリストに取り込むことができます。これらはファイルです。

1 10 2 3 4 5 6 7 8 9

次のコマンドを使用します。
for n in `ls|tail -8`; do mv $n ~/temp; done

1
xortion

これも機能することがわかりました:ls -1 [sort options] | tail -n2 | xargs -I {} -n 1 echo "mv \"{}\" ../t2/"

もちろん、エコーを削除する必要があります:ls -1 | tail -n2 | xargs -I {} -n 1 mv "{}" ../t2/

"{}"'{}'に置き換えることができます。実際には、最終的な実験として、(二重)引用符の削除も機能します。驚いたが、テスト済み。

0
tpb261