我有几个具有不同扩展名的文件和具有相同基名的目录,如本示例所示。
FileA.txt
FileA.html
FileA.directory/
FileB.txt
FileB.html
FileB.directory/
FileC.txt
FileC.html
FileC.directory/
我想创建一个 for 循环,我可以根据其基本名称将所有文件移动到相应的目录。结果如下
FileA.directory/FileA.txt
FileA.directory/FileA.html
FileB.directory/FileB.txt
FileB.directory/FileB.html
FileC.directory/FileC.txt
FileC.directory/FileC.html
我试图在此页面上找到与我的问题类似的几个建议,例如这个示例。但我找不到完全相似的问题。
for dir in .*/
do
for f in "$dir"*
do
base=${f#$dir}
mv "$base.*" "$dir"
done
done
但是我无法让它工作。
答案1
假设文件和目录的名称遵循相同的命名约定,因为它们共享一些共同的分组前缀,后跟一个点,并假设我们不知道文件或目录的文件名后缀:
topdir=.
for dirname in "$topdir"/*/; do
prefix=$( basename "$dirname" ) # $topdir/FileC.directory/ --> FileC.directory
prefix=${prefix%%.*} # FileC.directory --> FileC
for filename in "$topdir/$prefix".*; do
if [ ! -d "$filename" ]; then
mv -i "$filename" "$dirname"
fi
done
done
外层循环迭代目录中的所有目录$topdir
(此处设置为.
,当前目录)。这$prefix
将是目录名称的基本名称,删除第一个点后面的位。
一旦计算出前缀,同一$topdir
目录中共享相同前缀的非目录(文件)将被移动到该目录。
答案2
假设我们知道所有文件都有文件名后缀.html
或.txt
并且所有目录都有后缀.directory
,您可以使用:
for i in *.txt *.html
do
mv "$i" "${i%%.*}.directory/$i"
done
在您拥有文件的同一目录中运行此命令。它将从文件名中删除尾随的 .txt 和 .html,然后将文件移动到目标目录。
答案3
dirs=$(ls | grep ".d")
for d in $dirs
do
filename=$(echo $d | awk -F"." '{print $1}')
ls | grep -P "$filename.(?!(d))" | xargs -I{} mv '{}' '$d'
done
也许太冗长了,但它确实有效