【问题标题】:Rename directories based on number of files within in Linux根据 Linux 中的文件数重命名目录
【发布时间】:2012-04-26 08:08:19
【问题描述】:

我有以下布局:

  • d1
    • f1
    • f2
    • f3
  • d2
    • f4
    • f5
  • d3
    • f6
    • f7
    • f8
    • d4
      • f9

我想要做的是重命名根目录以包含其中包含的(递归)文件的数量。 格式不是很重要,只要它不太长。我希望能够每隔一小时左右将这个脚本作为 cron 运行以更新目录名称,因此在第一次运行后它会如下所示:

  • 3-d1
    • f1
    • f2
    • f3
  • 2-d2
    • f4
    • f5
  • 4-d3
    • f6
    • f7
    • f8
    • d4
      • f9

那么在第二次运行之后,可能又会添加和删除几个文件,现在看起来是这样的:

  • 1-d1
    • f1
  • 4-d2
    • f2
    • f3
    • f4
    • f5
  • 10-d3
    • f6
    • f7
    • f8
    • d4
      • f9
      • f10
      • f11
      • f12
      • f13
      • f14
      • f15

到目前为止,我有以下 bash 脚本,但我不知道如何对文件名进行正则表达式替换

#!/bin/bash

TARGETPATH=/home/pritchea/test
for CURDIR in `ls -l $TARGETPATH`
do
  if [ -d $TARGETPATH/$CURDIR ]; then
    echo "$CURDIR is a directory"
    FILECOUNT=`find $TARGETPATH/$CURDIR -type f | wc -l`
    echo " and there are $FILECOUNT file(s)";
  fi
done

【问题讨论】:

  • ls -l 还是ls -1?一般来说,可靠地解析ls 输出是一项危险的(或至少是困难的)业务;小心点。

标签: regex linux bash rename


【解决方案1】:

之前

.
├── d1
│   ├── f1
│   ├── f2
│   └── f3
├── d2
│   ├── f4
│   └── f5
└── d3
    ├── d4
    │   └── f9
    ├── f6
    ├── f7
    └── f8

在顶层目录运行命令

cd /home/pritchea/test

for i in *
do
    [[ -d $i ]] || continue
    n=${i#*-}
    c=$(find "$i" -type f -printf x | wc -c)
    [[ $i == $c-$n ]] && continue
    mv -f "$i" "$c-$n"
done

之后

.
├── 2-d2
│   ├── f4
│   └── f5
├── 3-d1
│   ├── f1
│   ├── f2
│   └── f3
└── 4-d3
    ├── d4
    │   └── f9
    ├── f6
    ├── f7
    └── f8

【讨论】:

    【解决方案2】:

    我就是这样做的。我遍历$TARGETPATH 中的所有目录,使用ls -l 检查每个$CURDIR 中存在多少不是目录的文件。注意:这可能不是最好的方法(find -f 可能会给出更好的结果;我没有检查符号链接等)。

    因为wc -l 倾向于给出类似于[ 1] 的输出,而不是[1],所以我使用sed 去除空格。

    从目录中删除数字(如果存在的话),这样我们就可以多次重新运行它,而不是最终得到看起来像这样的名称:2-3-dir,并检查 newdirname 是否不一样如CURDIR;如果是,那么运行mv 毫无意义。

    
    #!/bin/bash
    
    TARGETPATH=.
    for CURDIR in `ls -l $TARGETPATH`
    do
      if [ -d $TARGETPATH/$CURDIR ]; then
        echo "$CURDIR is a directory"
        #Also strip whitespace from FILECOUNT
        FILECOUNT=$(ls -l $CURDIR | grep ^- | wc -l | sed -e 's/[ \t]*//')
        echo " and there are $FILECOUNT file(s)";
    
        # We should remove the number from the directory.
        newdirname="$FILECOUNT"-"$(echo "$CURDIR" | sed -e 's/^[0-9]*-//')"
        echo " New directory name: ["$newdirname"]"
        # Now we move the old-dir to the new-dir. 
        if [[ "$CURDIR" != "$newdirname" ]]; then
        mv $TARGETPATH/$CURDIR $TARGETPATH/$newdirname
        fi  
      fi  
    done
    

    【讨论】:

      猜你喜欢
      • 2011-05-26
      • 2012-09-12
      • 2018-04-10
      • 2018-12-07
      • 1970-01-01
      • 1970-01-01
      • 2015-01-29
      • 2017-03-28
      • 2021-07-20
      相关资源
      最近更新 更多