将文件复制到文件夹的名称与父目录中的扩展名不同

时间:2017-08-26 06:43:37

标签: shell

我的档案是

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

2 个答案:

答案 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'

注意:

  1. 除非你特别希望shell破坏东西,否则总是将shell变量放在双引号中。

  2. 我们添加了测试[ -f "$file" ],以便我们只尝试移动常规文件,而不是目录。

  3. 目录将与${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 这样的目录(按字母顺序排列)