linux中目录的半复杂重构

时间:2013-09-06 22:27:30

标签: regex linux unix mv

我有一堆需要重组的目录。它们的格式如下:

./1993-02-22 - The Moon - Tallahassee, FL/**files**
./1993-02-23 - The Moon - Tallahassee, FL/**files**
./1993-02-24 - The Moon - Tallahassee, FL/**files**
./1993-02-25 - The Moon - Tallahassee, FL/**files**
./1993-03-01 - The Test - Null, FL/**files**

我想从每个文件夹的开头提取日期。例如,在正则表达式中:([0-9]{4})\-([0-9]{1,2})\-([0-9]{1,2})并将目录重新格式化为./year/month/day

所以,它应该输出:

./1993/02/22/**files**
./1993/02/23/**files**
./1993/02/24/**files**
./1993/02/25/**files**
./1993/03/01/**files**

如何从命令行执行此操作?

4 个答案:

答案 0 :(得分:1)

我以不同于Kent的方式理解这个问题。我以为你想从每个原始目录创建一个新的目录树并移动它包含的所有文件。如果您正在寻找,可以尝试使用脚本:

perl -MFile::Path=make_path -MFile::Copy=move -e '
    for ( grep { -d } @ARGV ) {
        @date = m/\A(\d{4})-(\d{2})-(\d{2})/;
        next unless @date;
        $outdir = join q{/}, @date;
        make_path( $outdir );
        move( $_, $outdir );
    }
' *

它从当前目录读取每个文件(*作为参数传递)并执行两步过滤。第一个是无目录文件的grep,第二个是未定义的@date。然后它将日期的组件连接到一个路径,如果不存在则创建它并将旧文件的所有文件移动到新文件。

测试:

这里显示ls -lR显示初始状态的结果:

.:
total 24
drwxr-xr-x 2 dcg dcg 4096 sep  7 00:56 1993-02-22 - The Moon - Tallahassee, FL
drwxr-xr-x 2 dcg dcg 4096 sep  7 00:56 1993-02-23 - The Moon - Tallahassee, FL
drwxr-xr-x 2 dcg dcg 4096 sep  7 00:56 1993-02-24 - The Moon - Tallahassee, FL
drwxr-xr-x 2 dcg dcg 4096 sep  7 00:57 1993-02-25 - The Moon - Tallahassee, FL
drwxr-xr-x 2 dcg dcg 4096 sep  7 00:57 1993-03-01 - The Test - Null, FL
drwxr-xr-x 2 dcg dcg 4096 sep  7 00:47 dummy_dir
-rw-r--r-- 1 dcg dcg    0 sep  7 00:47 dummy_file

./1993-02-22 - The Moon - Tallahassee, FL: 
total 0
-rw-r--r-- 1 dcg dcg 0 sep  7 00:56 file1
-rw-r--r-- 1 dcg dcg 0 sep  7 00:56 file2

./1993-02-23 - The Moon - Tallahassee, FL: 
total 0
-rw-r--r-- 1 dcg dcg 0 sep  7 00:56 file3

./1993-02-24 - The Moon - Tallahassee, FL: 
total 0
-rw-r--r-- 1 dcg dcg 0 sep  7 00:56 file4

./1993-02-25 - The Moon - Tallahassee, FL: 
total 0
-rw-r--r-- 1 dcg dcg 0 sep  7 00:57 file5
-rw-r--r-- 1 dcg dcg 0 sep  7 00:57 file6

./1993-03-01 - The Test - Null, FL: 
total 0
-rw-r--r-- 1 dcg dcg 0 sep  7 00:57 file7

./dummy_dir:
total 0

在运行上一个脚本后,请注意基本目录仅保留虚拟文件并创建树的根(1993)。运行相同的ls -lR会产生:

.:
total 8                                                                                                                                                                                                                                     
drwxr-xr-x 4 dcg dcg 4096 sep  7 00:59 1993                                                                                                                                                                                                 
drwxr-xr-x 2 dcg dcg 4096 sep  7 00:47 dummy_dir                                                                                                                                                                                            
-rw-r--r-- 1 dcg dcg    0 sep  7 00:47 dummy_file                                                                                                                                                                                           

./1993:                                                                                                                                                                                                                                     
total 8                                                                                                                                                                                                                                     
drwxr-xr-x 6 dcg dcg 4096 sep  7 00:59 02
drwxr-xr-x 3 dcg dcg 4096 sep  7 00:59 03

./1993/02:
total 16
drwxr-xr-x 2 dcg dcg 4096 sep  7 00:56 22
drwxr-xr-x 2 dcg dcg 4096 sep  7 00:56 23
drwxr-xr-x 2 dcg dcg 4096 sep  7 00:56 24
drwxr-xr-x 2 dcg dcg 4096 sep  7 00:57 25

./1993/02/22:
total 0
-rw-r--r-- 1 dcg dcg 0 sep  7 00:56 file1
-rw-r--r-- 1 dcg dcg 0 sep  7 00:56 file2

./1993/02/23:
total 0
-rw-r--r-- 1 dcg dcg 0 sep  7 00:56 file3

./1993/02/24:
total 0
-rw-r--r-- 1 dcg dcg 0 sep  7 00:56 file4

./1993/02/25:
total 0
-rw-r--r-- 1 dcg dcg 0 sep  7 00:57 file5
-rw-r--r-- 1 dcg dcg 0 sep  7 00:57 file6

./1993/03:
total 4
drwxr-xr-x 2 dcg dcg 4096 sep  7 00:57 01

./1993/03/01:
total 0
-rw-r--r-- 1 dcg dcg 0 sep  7 00:57 file7

./dummy_dir:
total 0

答案 1 :(得分:1)

假设您的文件存储在“旧”文件夹中,那么您可以编写一个shell脚本(避免使用“for”循环,因为文件名包含空格有困难):

mkdir -p new
ls -d -1 old/*/* | while read oldfile; do
    newfile=`echo "$oldfile" | sed -r 's#^old/([0-9]{4})\-([0-9]{1,2})\-([0-9]{1,2})(.*)$#new/\1/\2/\3/\4#'`
    newdir=` echo $newfile | sed 's#/[^/]*$##'`
    echo "Creating \"$newdir\""
    mkdir -p "$newdir"
    echo "Moving files from \"$oldfile\" to \"$newfile\""
    cp -r "$oldfile" "$newfile"
done

脚本输出:

Creating "new/1993/02/22/ - The Moon - Tallahassee, FL"
Moving files from "old/1993-02-22 - The Moon - Tallahassee, FL/test" to "new/1993/02/22/ - The Moon - Tallahassee, FL/test"
Creating "new/1993/02/23/ - The Moon - Tallahassee, FL"
Moving files from "old/1993-02-23 - The Moon - Tallahassee, FL/test" to "new/1993/02/23/ - The Moon - Tallahassee, FL/test"
Creating "new/1993/02/24/ - The Moon - Tallahassee, FL"
Moving files from "old/1993-02-24 - The Moon - Tallahassee, FL/test" to "new/1993/02/24/ - The Moon - Tallahassee, FL/test"
Creating "new/1993/02/25/ - The Moon - Tallahassee, FL"
Moving files from "old/1993-02-25 - The Moon - Tallahassee, FL/test" to "new/1993/02/25/ - The Moon - Tallahassee, FL/test"
Creating "new/1993/03/01/ - The Tes - Null, FL"
Moving files from "old/1993-03-01 - The Tes - Null, FL/test2" to "new/1993/03/01/ - The Tes - Null, FL/test2"

你会在......“新”文件夹中找到你的新树:

$ tree old new
old
├── 1993-02-22 - The Moon - Tallahassee, FL
│   └── test
├── 1993-02-23 - The Moon - Tallahassee, FL
│   └── test
├── 1993-02-24 - The Moon - Tallahassee, FL
│   └── test
├── 1993-02-25 - The Moon - Tallahassee, FL
│   └── test
└── 1993-03-01 - The Tes - Null, FL
    └── test2
new
└── 1993
    ├── 02
    │   ├── 22
    │   │   └──  - The Moon - Tallahassee, FL
    │   │       └── test
    │   ├── 23
    │   │   └──  - The Moon - Tallahassee, FL
    │   │       └── test
    │   ├── 24
    │   │   └──  - The Moon - Tallahassee, FL
    │   │       └── test
    │   └── 25
    │       └──  - The Moon - Tallahassee, FL
    │           └── test
    └── 03
        └── 01
            └──  - The Tes - Null, FL
                └── test2

答案 2 :(得分:0)

像这样?

kent$  awk '{gsub(/-/,"/",$1);sub(/^[^/]*\//,"/",$NF);print $1$NF}' file
./1993/02/22/**files**
./1993/02/23/**files**
./1993/02/24/**files**
./1993/02/25/**files**
./1993/03/01/**files**

答案 3 :(得分:0)

经过这么多评论之后,这是sed+awk

awk 'BEGIN{FS="-"}{print $1"/"$2"/"$3}' file | awk 'BEGIN{FS="**files**"}{print $1"/"FS}' | sed -e 's/ \//\//g'

./1993/02/22/**files**
./1993/02/23/**files**
./1993/02/24/**files**
./1993/02/25/**files**
./1993/03/01/**files**