在顺序编号的目录之间插入新的编号目录

时间:2017-09-13 17:07:10

标签: linux bash shell

我正在尝试将新目录插入已创建目录的列表中。例如,如果我有以下子目录列表:

00 01 02 03 04 05 06 07 08 09 10 11 12 13

我想插入一个名为04的新子目录,并将其余部分向上移动一个:

00 01 02 03 04 05 06 07 08 09 10 11 12 13 14

显然,我无法将旧的04移动到05,因为已经存在一个名为该目录的目录。子目录列表始终从00开始,可以在任何地方结束99(没有固定数量的目录),并且永远不会丢失任何子目录(即01 02 03 05永远不会发生)。如果可能的话,我希望用bash脚本来完成这一切;如果没有,我会得到任何帮助,我可以得到!

2 个答案:

答案 0 :(得分:0)

如果你让自己使用几个命令,那就不难了。 我想出了这个,我认为这是一个不错的方式,但还有其他一千种方法可以做到这一点

function insert_folder() {

    local insert=$(echo $1 | sed -E 's/0([0-9])/\1/')

   `# Find all of the folders that match the pattern`            \
    find . -iregex "./[0-9][0-9]" -exec basename {} \;           \
   `# Remove leading 0's for now since it confuses bash`         \
    | sed -E 's/0([0-9])/\1/'                                    \
   `# Sort the folders largest to smallest (prevent collisions)` \
    |sort -rn                                                    \
   `# For each folder mv if greater than instert value`          \
    | xargs -I {} bash -c "
          if [ {} -ge ${insert} ]; then 
              mv \$(printf '%02d' {}) \$(printf '%02d' \$(({}+1))); 
          fi
    " 
    mkdir $1
}


find . -type f
> ./00/00.txt
> ./01/01.txt
> ./02/02.txt
> ./03/03.txt
> ./04/04.txt
> ./05/05.txt
> ./08/08.txt
> ./09/09.txt
> ./10/10.txt
> ./11/11.txt

insert_folder 05
find . \( -type f -or -name 05 \)  
> ./00/00.txt                          
> ./01/01.txt                          
> ./02/02.txt                          
> ./03/03.txt                                                           
> ./04/04.txt                          
> ./05
> ./06/05.txt                          
> ./09/08.txt                          
> ./10/09.txt                          
> ./11/10.txt                          
> ./12/11.txt                          
> ./13/12.txt                          

答案 1 :(得分:0)

以下是使用直接Bash解决问题的方法,没有外部命令(mv除外):

#!/bin/bash

newdir=$1

# Put all directories into array
dirs=(*/)

# Remove trailing "/" from each array element
dirs=("${dirs[@]/%\/}")

# Get index of last directory
lastidx=$(( ${#dirs[@]} - 1 ))

# Loop over directories, starting with last, down to the one with the same
# name as the one being inserted
# Use 10# to force decimal instead of octal interpretation of name
for (( idx = lastidx; idx >= 10#$newdir; --idx )); do
    # New name of directory is current name plus 1
    # Again 10# to avoid confusion because of leading zeros interpreted as
    # octal values
    printf -v newname '%02d' "$(( 10#${dirs[idx]} + 1 ))"
    echo "Renaming ${dirs[idx]} to $newname"
    mv "${dirs[idx]}" "$newname"
done

对于像

这样的现有目录结构
.
├── 00
├── 01
├── 02
├── 03
├── 04
├── 05
├── 06
├── 07
├── 08
├── 09
├── 10
├── 11
├── 12
└── 13

你可以像

一样使用它
$ ./insertdir 04
Renaming 13 to 14                
Renaming 12 to 13                
Renaming 11 to 12                
Renaming 10 to 11                
Renaming 09 to 10                
Renaming 08 to 09                
Renaming 07 to 08                
Renaming 06 to 07                
Renaming 05 to 06                
Renaming 04 to 05  

并以

结束
.
├── 00
├── 01
├── 02
├── 03
├── 05
├── 06
├── 07
├── 08
├── 09
├── 10
├── 11
├── 12
├── 13
└── 14

即,脚本并没有真正插入任何内容 - 它为新目录腾出了空间。