用于语义文件结构创建的bash

时间:2010-11-02 19:06:28

标签: bash hierarchy semantics organization

更新2010-11-02 7p:缩写说明;发布了最初的bash解决方案。


描述

我想创建一个语义文件结构来更好地组织我的数据。我不想去像recoll,strigi或beagle这样的路线;我不想要任何gui和完全控制。最接近的可能是oyepa甚至更近,Tagsistant

这是一个想法:一个人维护他们文件的“常规”树。例如,我的项目文件夹组织如下:

 ,---
 | ~/proj1
 | ---- ../proj1_file1[tag1-tag2].ext
 | ---- ../proj1_file2[tag3]_yyyy-mm-dd.ext
 | ~/proj2
 | ---- ../proj2_file3[tag2-tag4].ext
 | ---- ../proj1_file4[tag1].ext
 `---

proj1,proj2是我的项目的简短缩写。

然后我想要做的是递归遍历目录并获得以下内容:

  • proj ID
  • 标记
  • 扩展

每个文件都将形成一个完整的“标签列表”。

然后,在用户定义的目录中,将基于这些标记创建“语义层次结构”。这有点长,所以只需看一下为名称中包含tag2的所有文件创建的目录结构:

,---
| ~/tag2
| --- ../proj1_file1[tag1-tag2].ext -> ~/proj1/proj1_file1[tag1-tag2].ext
| --- ../proj2_file3[tag2-tag4].ext -> ~/proj2/proj2_file3[tag2-tag4].ext
| ---../tag1
| ------- ../proj1_file1[tag1-tag2].ext -> ~/proj1/proj1_file1[tag1-tag2].ext
| --- ../tag4
| ------- ../proj2_file3[tag2-tag4].ext -> ~/proj2/proj2_file3[tag2-tag4].ext
| --- ../proj1
| ------- ../proj1_file1[tag1-tag2].ext -> ~/proj1/proj1_file1[tag1-tag2].ext
| --- ../proj2
| ------- ../proj2_file3[tag2-tag4].ext -> ~/proj2/proj2_file3[tag2-tag4].ext
`---

换句话说,使用文件标签的所有组合创建目录,每个目录包含具有这些标签的实际文件的符号链接。我省略了文件类型目录,但这些目录也存在。它在类型上看起来非常混乱,但我认为效果非常酷。然后,人们可以沿着许多“标签面包屑”对给定文件进行细化。

到目前为止我的想法:

  • ls -R在顶级目录中获取所有文件名
  • 识别文件名中带[和]的文件(标记文件)
  • 剩下的,输入一个循环:
    • 删除项目ID,标签和扩展程序
    • 根据标签
    • 创建所有必要的目录
    • 为所有创建的目录中的文件创建符号链接

第一个解决方案! 2010-11-3 7p

这是我目前的工作代码。它仅适用于顶级目录中的文件,尚未确定扩展类型,仅适用于2个标记+项目ID,每个文件总共3个标记。这是一个黑客手动突突解决方案,但也许它可以帮助别人看到我正在做什么以及如何做得更好:

#!/bin/bash

########################
#### User Variables ####
########################

## set top directory for the semantic filer
## example: ~/semantic
## result will be ~/semantic/tag1, ~/semantic/tag2, etc.
top_dir=~/Desktop/semantic

## set document extensions, space separated
## example: "doc odt txt"
doc_ext="doc odt txt"

## set presentation extensions, space separated
pres_ext="ppt odp pptx"

## set image extensions, space separated
img_ext="jpg png gif"

#### End User Variables ####


#####################
#### Begin Script####
#####################

cd $top_dir

ls -1 | (while read fname;
do
   if [[ $fname == *[* ]]
   then

     tag_names=$( echo $fname | sed -e 's/-/ /g' -e 's/_.*\[/ /' -e 's/\].*$//' )

     num_tags=$(echo $tag_names | wc -w)

     current_tags=( `echo $tag_names | sed -e 's/ /\n/g'` )
     echo ${current_tags[0]}
     echo ${current_tags[1]}
     echo ${current_tags[2]}

     case $num_tags in
       3)

       mkdir -p ./${current_tags[0]}/${current_tags[1]}/${current_tags[2]}
       mkdir -p ./${current_tags[0]}/${current_tags[2]}/${current_tags[1]}
       mkdir -p ./${current_tags[1]}/${current_tags[0]}/${current_tags[2]}
       mkdir -p ./${current_tags[1]}/${current_tags[2]}/${current_tags[0]}
       mkdir -p ./${current_tags[2]}/${current_tags[0]}/${current_tags[1]}
       mkdir -p ./${current_tags[2]}/${current_tags[1]}/${current_tags[0]}

       cd $top_dir/${current_tags[0]}
       echo $PWD
       ln -s $top_dir/$fname
       ln -s $top_dir/$fname ./${current_tags[1]}/$fname
       ln -s $top_dir/$fname ./${current_tags[2]}/$fname

       cd $top_dir/${current_tags[1]}
       echo $PWD
       ln -s $top_dir/$fname
       ln -s $top_dir/$fname ./${current_tags[0]}/$fname
       ln -s $top_dir/$fname ./${current_tags[2]}/$fname

       cd $top_dir/${current_tags[2]}
       echo $PWD
       ln -s $top_dir/$fname
       ln -s $top_dir/$fname ./${current_tags[0]}/$fname
       ln -s $top_dir/$fname ./${current_tags[1]}/$fname

       cd $top_dir
       ;;

       esac

   fi

done
)

它实际上非常整洁。如果您想尝试,请执行以下操作:

  • 在某处创建一个目录
  • 使用touch创建一堆上述格式的文件:proj_name [tag1-tag2] .ext
  • 定义top_dir变量
  • 运行脚本
  • 玩耍!

待办事项

  • 使用“ls -R”进行此工作,以便在我的实际树中进入子目录
  • 健壮性检查
  • 考虑转换语言;嘿,我一直想学习perl和/或python!

仍然对您提出的任何建议持开放态度。谢谢!

2 个答案:

答案 0 :(得分:0)

每个标签可能都是这样的吗?

find . -type f|grep -Z "[[-]$tag[]-]"| \
xargs -0 -I %%% ln -s "../../%%%" "tagfolder/$tag/"

注意:第二行不起作用,不知道为什么。

答案 1 :(得分:0)

嗯,很大的问题,短暂的休息时间太大了......

但我可以举例说明你可以用各种方法构建脚本......

#!/bin/sh

ls -1 / | (while read fname; do
    echo "$fname"
    test=hello
    # example transformation...
    test2=`echo $fname | tr a-z A-Z`
    echo "$test2"
  done
  echo post-loop processing here, $test
  # then finally close the subshell with a right paren
)