web-dev-qa-db-ja.com

.txtで終わっていないすべてのファイルを移動する

ディレクトリ/home/username/dataには、ファイルとディレクトリの両方があります。これらのファイル名の一部は.txtで終わります(これをテキストファイルと呼びます)。同じことがサブディレクトリでも起こります。

サブディレクトリの1つはother_filesと呼ばれます(その完全パスは/home/username/data/other_files/です)。

.txtで終わらないすべてのファイルを移動したいのルート/home/username/dataother_filesに移動します。


ループでできるかもしれませんが、それは私が望んでいることではありません。コマンドとパイピングを使用したい。これは簡単だと私は信じています。 mvfindgrepxargsの組み合わせで実現できますが、方法はわかりません。

だから私はテキストファイルを一致させようとするのに行き詰まっています(それからそれらを除くすべてのものを一致させる方法を考えるために)。以下では、現在のディレクトリが/home/username/dataであると想定しています。
最初に私はfind . | grep -E "*\.txt"に行きましたが、これはサブディレクトリにあるものを含むすべてのテキストファイルに一致します。
そこで、私はfind . | grep -E "\./*\.txt"を試して、同じマッチが得られるかどうかを確認し、目標に向かって進んでいきましたが、これは何にもマッチせず、ここが行き詰まっています。


質問の最初に説明したことをするにはどうすればよいですか?

10
Moving Man

単純なシェルループバリアント(bash内):

_shopt -s extglob dotglob nullglob

for pathname in ~username/data/!(*.txt); do
    ! test -d "$pathname" && mv "$pathname" ~username/data/other_files
done
_

最初の行で設定されたシェルオプションは、bashシェルが拡張グロビングパターン(!(*.txt)で_.txt_で終わらないすべての名前に一致する)を有効にし、グロブパターンが一致するようにします隠された名前で、何も一致しない場合、パターンは何にも拡張されません。

ループの本体は、ディレクトリ(またはディレクトリへのシンボリックリンク)であるものはすべてスキップし、それ以外のすべてを指定されたディレクトリに移動します。

findおよびGNU mvと同等のもの(存在する場合はシンボリックリンクをディレクトリに移動し、mvを一度にできるだけ多くのファイルを使用できますが、それらだけが違います)。

_find ~username/data -maxdepth 1 ! -type d ! -name '*.txt' \
    -exec mv -t ~username/data/other_files {} +
_

関連:

13
Kusalananda
find /home/username/data -maxdepth 1 -type f ! -name '*.txt' -exec mv {} /home/username/data/other_files/ \;
  • トップディレクターの最大深度制限
  • typeは、ディレクトリではなく、ファイルのみが検出されることを保証します
7
nohillside

このコードは、「。txt」で終わっていないすべてのファイルをターゲットフォルダーに移動しますが、異なるパスに同じ名前のファイルがある場合、エラーがスローされます。

find /home/username/data ! -name "*.txt" -type f -maxdepth 1 -exec mv {} /home/username/data/other_files/ \;
2
Tamas H.

次の行は、現在のディレクトリで*.txtではなく、パスでもないすべてのファイルと隠しファイルを見つけ、それらをnewpathに移動します。

ls -1p | grep -v "^.*\.txt$" | grep -v ".*/$" | xargs mv -vt newpath

以下は同じですが、隠しファイルも移動します:

ls -1ap | grep -v "^.*\.txt$" | grep -v ".*/$" | xargs mv -vt newpath

両方のコマンドラインはディレクトリを再帰的にスキャンせず、ディレクトリを移動しません

スペースを含むファイル名がある場合は、次を使用できます。

ls -1ap | grep -v "^.*\.txt$" | grep -v ".*/$" | xargs -d'\n' printf "\"%s\"\n" | xargs mv -vt newpath

1
Sir Jo Black