
ファイルのリストを含むディレクトリがあります。これらのファイルはすべて名前にスペースがあります。
拡張子を除いて、ファイル名を含む各ファイルのディレクトリを作成したいと思います(すべてのファイルの拡張子は.docです)。
たとえば、
私のディレクトリの内容
first file.doc
second file.doc
third file.doc
予想される結果
first file/first file.doc
second file/second file.doc
third file/third file.doc
作成するディレクトリ名を確認するには、次のコマンドを使用します。
find . -maxdepth 1 -name "*.doc" | awk -F ".doc" '{print $1}'
結果は次のとおりです。
first file
second file
third file
各項目に対してディレクトリを作成する必要があることを理解してください。
私は成功せずに次のことを試しました。
find . -maxdepth 1 -name "*.doc" | awk -F ".doc" '{print $1}' -exec mkdir '{}' \;
#error with awk: it cannot open the file -exec because it does not exist
mkdir `find . -maxdepth 1 -name "*.doc" | awk -F ".doc" '{print $1}'`
#it creates several directories per name because there are spaces in the names
mkdir `"find . -maxdepth 1 -name "*.doc" | awk -F ".doc" '{print $1}'"`
#-bash: find . -maxdepth 1 -name *.doc | awk -F .doc '{print }': command not found
mkdir "`find . -maxdepth 1 -name "*.doc" | awk -F ".doc" '{print $1}'`"
#it tries to create a unique directory with all the file names as a single name, which is not good of course
可能であれば、ファイル名からすべてのスペースを削除したいのですが、プロジェクトの制約に合うようにしてください。
これらのディレクトリを作成できるようになったら、一致するディレクトリ内のすべてのファイルを移動する方法を理解する必要があります。これはすべて1つのコマンドで実行できます。
私はbashとRedHat 2.6を使用しています。
ご協力ありがとうございます。ローラン
答え1
そしてzsh
:
mkdir -p -- *.doc(:r)
または:
for f (*.doc) {
mkdir -p -- $f:r &&
mv -- $f $f:r/
}
同等bash
(すべてのPOSIXシェルでも動作しますがzsh
):
for f in *.doc; do
mkdir -p -- "${f%.*}" &&
mv -- "$f" "${f%.*}/"
done
(隠しファイルは含まれませんのでご注意ください)
答え2
ファイル/ディレクトリ名のスペースは、名前が正しく引用されている限り大丈夫です。
find . -maxdepth 1 -name "*.doc" | while IFS= read -r f; do
mkdir -- "${f%.doc}";
done
答え3
cd /path/to/dir
( set -- *\ *
printf 'd="%s" ; mkdir ./"${d%%.doc}"\n' "$@"
) | . /dev/stdin
シェルglobを使用してサブシェルのパラメータを設定し、printfを使用してパイプにデータを提供できます。パイプをスクリプトソースとして使用します。
各ディレクトリのファイルを移動するには、次の手順を実行します。
cd /path/to/dir
( set -- *\ *
printf 'f="%s" ; d="${f%%.doc}"
mkdir ./"$d" ; echo "mv ./\"$f\" ./\"$d\"/\"$f\""\n' "$@"
) | . /dev/stdin
注:コミットする前に出力をテストしたいので、意図的に上記の内容をエコーに制限しました。
修正済み - printfに2%の割合を使用することを忘れました。
ところで、私はこれをテストしました:
% printf 'touch ./"%s file.doc"\n' first second third fourth fifth |
. /dev/stdin
% ls
> fifth file.doc first file.doc fourth file.doc second file.doc third file.doc
% ( set -- *\ *
printf 'f="%s" ; d="${f%%.doc}"
mkdir ./"$d" ; mv ./"$f" ./"$d"\n' "$@"
) | . /dev/stdin
% ls
> fifth file first file fourth file second file third file
% cd fifth\ file ; ls
> fifth file.doc