回答:
以下のpythonスクリプトがジョブを実行します。非表示のファイルは、拡張子のないファイルと同様に、フォルダーに個別に保存されます。
より広い範囲の目的に使用される可能性があるため、いくつかのオプションを追加しました。
exclude = ()
remove_emptyfolders = True
またはFalse
)shutil.move(subject, new_dir+"/"+name)
沿って:
shutil.copy(subject, new_dir+"/"+name)
スクリプト:
#!/usr/bin/env python3
import os
import subprocess
import shutil
# --------------------------------------------------------
reorg_dir = "/path/to/directory_to_reorganize"
exclude = (".jpg") # for example
remove_emptyfolders = True
# ---------------------------------------------------------
for root, dirs, files in os.walk(reorg_dir):
for name in files:
subject = root+"/"+name
if name.startswith("."):
extension = ".hidden_files"
elif not "." in name:
extension = ".without_extension"
else:
extension = name[name.rfind("."):]
if not extension in exclude:
new_dir = reorg_dir+"/"+extension[1:]
if not os.path.exists(new_dir):
os.mkdir(new_dir)
shutil.move(subject, new_dir+"/"+name)
def cleanup():
filelist = []
for root, dirs, files in os.walk(reorg_dir):
for name in files:
filelist.append(root+"/"+name)
directories = [item[0] for item in os.walk(reorg_dir)]
for dr in directories:
matches = [item for item in filelist if dr in item]
if len(matches) == 0:
try:
shutil.rmtree(dr)
except FileNotFoundError:
pass
if remove_emptyfolders == True:
cleanup()
不要な重複ファイルの上書きのリスクがある場合
いくつかの余分な行を犠牲にして、可能な重複の上書きを防ぐことができます。以下のコードでは、複製の名前が次のように変更されます。
duplicate_1_filename, duplicate_2_filename
等
スクリプト:
#!/usr/bin/env python3
import os
import subprocess
import shutil
# --------------------------------------------------------
reorg_dir = "/path/to/directory_to_reorganize"
exclude = (".jpg") # for example
remove_emptyfolders = True
# ---------------------------------------------------------
for root, dirs, files in os.walk(reorg_dir):
for name in files:
subject = root+"/"+name
if name.startswith("."):
extension = ".hidden_files"
elif not "." in name:
extension = ".without_extension"
else:
extension = name[name.rfind("."):]
if not extension in exclude:
new_dir = reorg_dir+"/"+extension[1:]
if not os.path.exists(new_dir):
os.mkdir(new_dir)
n = 1; name_orig = name
while os.path.exists(new_dir+"/"+name):
name = "duplicate_"+str(n)+"_"+name_orig
n = n+1
newfile = new_dir+"/"+name
shutil.move(subject, newfile)
def cleanup():
filelist = []
for root, dirs, files in os.walk(reorg_dir):
for name in files:
filelist.append(root+"/"+name)
directories = [item[0] for item in os.walk(reorg_dir)]
for dr in directories:
matches = [item for item in filelist if dr in item]
if len(matches) == 0:
try:
shutil.rmtree(dr)
except FileNotFoundError:
pass
if remove_emptyfolders == True:
cleanup()
OPを念頭に置いて、使用方法に関する指示を追加するのを忘れていました。重複した質問が表示される場合があります(実際に表示されます)が、それでも便利な場合があります。
reorganize.py
スクリプトのヘッドセクションで、ターゲットディレクトリ(再編成するファイルを含む)を設定します。
reorg_dir = "/path/to/directory_to_reorganize"
(ディレクトリにスペースが含まれる場合は引用符を使用してください)
除外する可能性のある拡張子(おそらく以下のようななし):
exclude = ()
後で空のフォルダーを削除する場合:
remove_emptyfolders = True
次のコマンドを使用してスクリプトを実行します。
python3 /path/to/reorganize.py
注意:moveの代わりにファイルをコピーしたい場合は、次を置き換えます:
shutil.move(subject, new_dir+"/"+name)
沿って:
shutil.copy(subject, new_dir+"/"+name)
最初に小さなサンプルを試してください。
find
やや複雑なexec
コマンドで使用できます:
find . -iname '*?.?*' -type f -exec bash -c 'EXT="${0##*.}"; mkdir -p "$PWD/${EXT}_dir"; cp --target-directory="$PWD/${EXT}_dir" "$0"' {} \;
# '*?.?*' requires at least one character before and after the '.',
# so that files like .bashrc and blah. are avoided.
# EXT="${0##*.}" - get the extension
# mkdir -p $PWD/${EXT}_dir - make the folder, ignore if it exists
乾式運転の場合に交換cp
しecho
てください。
より効率的で整頓されているのは、bash
コマンドをスクリプトに保存することです(例 :)/path/to/the/script.sh
:
#! /bin/bash
for i
do
EXT="${i##*.}"
mkdir -p "$PWD/${EXT}_dir"
mv --target-directory="$PWD/${EXT}_dir" "$i"
done
そして、実行しますfind
:
find . -iname '*?.?*' -type f -exec /path/to/the/script.sh {} +
このアプローチは非常に柔軟です。たとえば、拡張子(filename.ext
)の代わりにファイル名を使用するには、これをEXT
次のように使用します。
NAME="${i##*/}"
EXT="${NAME%.*}"
*.fig.bak
つまたは複数ではありませんが、.profile/.bashrc
少なくとも拡張子を持つファイルのみを処理する必要があります。ありがとう。
ls | gawk -F. 'NF>1 {f= $NF "-DIR"; system("mkdir -p " f ";mv " $0 " " f)}'
拡張機能のリストの計算(移動後):
ls -d *-DIR
拡張のリストの計算(移動する前):
ls -X | grep -Po '(?<=\.)(\w+)$'| uniq -c | sort -n
(この最後の例では、各拡張子のファイル数を計算してソートしています)
ls -X
。反対する理由についてはls
、unix.stackexchange.com / q / 128985/70524およびunix.stackexchange.com/q/112125/70524を参照してください。あなたがすることを達成するために、私はもっと長い道のりに行きます:(カウントが必要な場合find . -type f -name '*?.?*' -print0 | sed -z 's/.*\.//' | sort -zu
、オプション| uniq -cz
で)。そしてfind ... -print0 | gawk -v RS='\0'
(それはあまりポータブルではありませんが)最初のものです。
このシェルスクリプトを試してください。
#!/bin/sh
src=`dirname "$1"`/`basename "$1"`;
for file in "$src"/*?.?*; do
if test -f "$file"; then
dest="$src${file##*.}"_files;
mkdir -p "$dest";
mv "$file" "$dest";
fi;
done;
# pass the directory to re-organize as first argument
# moves only regular files which have extension
# ignores other type of files including
# files having no extension, hidden files, directories, and links.
filepath
で置換する必要がありfile
ます。それを直接修正します。
for file in "$src"/*?.?*; do ..
read
予期しない動作が発生する場合があります。また、mkdirおよびmvコマンドで変数を引用する必要があります。
for i in *; do printf "%s\n" "$i"; done; for i in $(ls -d); do printf "%s\n" "$i"; done
-iname '*.*'
私が心配していたコーナーケースの世話をする必要があります...素敵なアイデア!