我的档案是
1996-08-30T02.11.41.940_10
1997-03-04T17.24.17.650_17
1997-04-01T15.43.26.390_20
和文件夹
1996-08-30T02.11.41.940_5.1
1997-03-04T17.24.17.650_5.0
1997-04-01T15.43.26.390_4.5
文件和文件夹位于相同的目录中。我想将文件移动到名称相同,扩展名不同的文件夹 例如: 文件1996-08-30T02.11.41.940_10应该在文件夹中移动1996-08-30T02.11.41.940_5.1
我试过了,但没有用
for file in ./*T* ; do mv -v $file ${file%_*}; done
答案 0 :(得分:2)
你非常接近:
$ for file in ./* ; do [ -f "$file" ] && mv -v "$file" "${file%_*}"*/; done
'./1996-08-30T02.11.41.940_10' -> './1996-08-30T02.11.41.940_5.1/1996-08-30T02.11.41.940_10'
'./1997-03-04T17.24.17.650_17' -> './1997-03-04T17.24.17.650_5.0/1997-03-04T17.24.17.650_17'
'./1997-04-01T15.43.26.390_20' -> './1997-04-01T15.43.26.390_4.5/1997-04-01T15.43.26.390_20'
注意:
除非你特别希望shell破坏东西,否则总是将shell变量放在双引号中。
我们添加了测试[ -f "$file" ]
,以便我们只尝试移动常规文件,而不是目录。
目录将与${file%_*}"*/
匹配。根据问题的描述,我们假设只有一个这样的目录。
答案 1 :(得分:1)
这是@ John1024的类似方法,但依赖于bash功能。
首先,创建一个关联数组,映射"公共根"到目录名称:
declare -A dirs
for d in */; do dirs["${d%_*}"]=$d; done
然后,迭代文件,然后进入具有公共根目录的目录
for f in *; do
[[ -f $f ]] || continue
root=${f%_*}
if [[ ${dirs[$root]} ]]; then
mv -v "$f" "${dirs[$root]}"
else
echo "error: no directory for '$f'"
fi
done
'1996-08-30T02.11.41.940_10' -> '1996-08-30T02.11.41.940_5.1/1996-08-30T02.11.41.940_10'
'1997-03-04T17.24.17.650_17' -> '1997-03-04T17.24.17.650_5.0/1997-03-04T17.24.17.650_17'
'1997-04-01T15.43.26.390_20' -> '1997-04-01T15.43.26.390_4.5/1997-04-01T15.43.26.390_20'
这解决了假设只有一个目录具有公共根目录:文件将被移动到 last 这样的目录(按字母顺序排列)