“覆盖”文件,空间仍然被占用,它们丢失了吗?

I'm*_*tor 11 command-line bash files

如此愚蠢的不耐烦,我在我的 19.04 服务器上使用了以下脚本,试图将一堆视频文件移动到带有前缀的文件夹中:

dirs=(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)
shopt -s nocasematch

for file in *
do
    for dir in "${dirs[@]}"
    do

     if [ -d "$file" ]; then
      echo 'this is a dir, skipping'
      break
     else
      if [[ $file =~ ^[$dir] ]]; then
       echo "----> $file moves into -> $dir <----"
       mv "$file" "$dir"
       break
      fi
     fi
  done
done
Run Code Online (Sandbox Code Playgroud)

不知道哪里出了问题,但不是将文件移动到文件夹,而是转到了一个单一的输出..所以:

----> a1.ts moves into -> A <----
----> a2.ts moves into -> A <----
----> a3.ts moves into -> A <----
----> a4.ts moves into -> A <----
----> a5.ts moves into -> A <----
----> c1.ts moves into -> C <----
----> c2.ts moves into -> C <----
----> c3.ts moves into -> C <----
----> c4.ts moves into -> C <----
----> c5.ts moves into -> C <----
Run Code Online (Sandbox Code Playgroud)

幸运的是,当我注意到它没有按预期进行并且没有遍历整个文件夹时,我立即停止了该过程 (CTRL+C)。

所以现在我得到了那些小于 Gb 的文件AC,从它的外观来看是一个单一的视频。

文件夹本身的总磁盘使用量中有 50Gb 下落不明,但计算机的整体磁盘空间保持不变。让我觉得文件没有被删除?

感谢任何帮助,谢谢:)

编辑:文件实际上已经消失了,只剩下最后一个要写入的文件,只需要一些时间来更新磁盘使用信息..故事的寓意,之前在模拟文件上运行您的脚本!

sud*_*dus 15

我认为这是问题所在:您应该已经创建了目录 A、B、C ... Z。如果您这样做了,该mv命令应该已将文件移动到这些目录中。

但如果没有,该mv命令会将文件移动到具有这些名称的文件中,A、B、C ...我认为这就是您所做的。

为了使 shellscript 更安全,您应该在开始移动之前让它创建目录(如果它们尚未存在)。

dirs=(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)

for dir in "${dirs[@]}"
do
 mkdir -p $dir
done
Run Code Online (Sandbox Code Playgroud)

如果你想要的东西来获得更安全,你也可以使用mv-i选项

   -i, --interactive
          prompt before overwrite
Run Code Online (Sandbox Code Playgroud)

  • 另一个使 `mv` 更安全的简单方法是养成在目标是目录时在目标名称后添加斜杠的习惯,即 `mv "$file" "$dir/"` (6认同)
  • 如果名称不存在,`touch` 会创建一个文件。所以在这种情况下它不会做你想要的。`mkdir -p` 可以多次使用脚本。 (2认同)

ter*_*don 7

@Sudodus 已经解释了出了什么问题,但这里有一个更简单的脚本版本供下次使用:

for letter in {a..z}; do 
    dir=${letter^}
    mkdir -p -- "$dir" 
    mv -- "$letter"* "${letter^^}"* "$dir"/
done
Run Code Online (Sandbox Code Playgroud)

解释

  • for letter in {a..z}; do:{a..z}扩展为a和之间的所有小写字母z

    $ echo {a..z}
    a b c d e f g h i j k l m n o p q r s t u v w x y z
    
    Run Code Online (Sandbox Code Playgroud)

    因此,这将遍历所有小写字母,将每个字母另存为$letter.

  • dir=${letter^}: 语法${var^^}返回变量的内容,$var第一个字符为大写(因为它只有一个字符,这就是我们所需要的)。因此,如果$lettera,则${letter^^}A,因此$dir将是当前 的大写版本$letter

  • mkdir -p -- "$dir": 创建目录。如果它已经存在,则什么都不做 ( -p)。该-- 表示的选项的结束,并防止先从名称很有用-
  • mv -- "$letter"* "${letter^}"* "$dir" :将每个文件(或目录)移动到相关目标。

这样做的问题是它还会移动您可能拥有的任何目录。它不会移动目标目录,因为它们要么不存在,要么您将尝试将它们移动到它们自身中,但任何不是目标目录的现有目录都将被移动。

如果这是一个问题,你将不得不做这样的事情:

for file in *; do 
    if [[ ! -d "$file" ]]; then 
        letter="${file:0:1}"
        dir="${letter^}"
        mkdir -p -- "$dir"
        mv -- "$file" "$dir"/
    fi
done
Run Code Online (Sandbox Code Playgroud)