ディレクトリ内に/home/username/data
ファイルとディレクトリの両方があります。これらのファイル名のいくつかは.txt
次のように終わります。テキストファイル)、他の人はそうではありません。サブディレクトリでも同じことが起こります。
サブディレクトリの1つother_files
(フルパス/home/username/data/other_files/
)を呼び出します。
始まらないすべてを移動したい.txt
ルートに /home/username/data
到着するother_files
。
ループを使用してこれを実行できますが、これは私が望むものではありません。コマンドとパイプを使いたいです。私はそれが簡単だと確信しています。私はそれを見ません。 、、の組み合わせがトリックを実行する必要がありますが、どのようにmv
すべきかわかりません。find
grep
xargs
だから私はテキストファイルを一致させようとしました(そしてそれを除いてすべてを一致させる方法を見つけようとしました)。以下は、現在のディレクトリがあると仮定します/home/username/data
。
最初に選択しましたが、find . | grep -E "*\.txt"
サブディレクトリのファイルを含むすべてのテキストファイルと一致します。
だからfind . | grep -E "\./*\.txt"
同じマッチが出てくるかどうかを調べて目標に向かって努力しましたが、何もマッチしなかったし、そこで詰まっていました。
質問の冒頭で説明した内容をどのように実行しますか?
答え1
単純なシェルループバリエーション(in bash
):
shopt -s extglob dotglob nullglob
for pathname in ~username/data/!(*.txt); do
! test -d "$pathname" && mv "$pathname" ~username/data/other_files
done
最初の行に設定されているシェルオプションを使用すると、シェルbash
で拡張globbingパターンを有効にします(.!(*.txt)
で終わらない.txt
すべての名前と一致)。
ループ本文は、ディレクトリ(またはディレクトリへのシンボリックリンク)内のすべてのエントリをスキップし、他のすべてのエントリを指定されたディレクトリに移動します。
find
GNUに対応する機能mv
(シンボリックリンクがある場合はディレクトリに移動し、mv
同時に多くのファイルを呼び出しますが、これが唯一の違いです):
find ~username/data -maxdepth 1 ! -type d ! -name '*.txt' \
-exec mv -t ~username/data/other_files {} +
関連:
答え2
find /home/username/data -maxdepth 1 -type f ! -name '*.txt' -exec mv {} /home/username/data/other_files/ \;
- 最高取締役の最大深度制限
- typeは、ディレクトリではなくファイルのみが見つかることを保証します。
答え3
このコードは「.txt」で終わらないすべてのファイルをターゲットフォルダに移動する必要がありますが、別のパスに同じ名前のファイルがあるとエラーが発生します。
find /home/username/data ! -name "*.txt" -type f -maxdepth 1 -exec mv {} /home/username/data/other_files/ \;
答え4
次の行は、*.txt
現在のディレクトリでパス以外のすべてのファイルと隠しファイルを見つけ、新しいパスに移動します。
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