展平目录结构并保留重复文件

时间:2013-12-27 11:28:43

标签: bash shell unix zsh

我有一个如下所示的目录结构:

foo
├── 1.txt
├── 2.txt
├── 3.txt
├── 4.txt
└── bar
    ├── 1.txt
    ├── 2.txt
    └── 5.txt

我想展平这个目录结构,以便所有文件都在foo目录中并保留重复文件:

foo
├── 1.txt
├── 2.txt
├── 3.txt
├── 4.txt
├── bar-1.txt
├── bar-2.txt
└── bar-5.txt

重命名的重复项的文件名无关紧要。

我可以使用简单的Unix单行或简单的shell脚本吗?

3 个答案:

答案 0 :(得分:11)

这应该有效:

target="/tmp/target"; find . -type f | while read line; do outbn="$(basename "$line")"; while true; do if [[ -e "$target/$outbn" ]]; then outbn="z-$outbn"; else break; fi; done; cp "$line" "$target/$outbn"; done

格式化为非单行:

target="/tmp/target"
find . -type f | while read line; do
  outbn="$(basename "$line")"
  while true; do
    if [[ -e "$target/$outbn" ]]; then
      outbn="z-$outbn"
    else
      break
    fi
  done
  cp "$line" "$target/$outbn"
done

请务必在您的foo目录中运行该命令,并将$target变量设置为目标目录。

示例:

$ find foo
foo
foo/1
foo/2
foo/3
foo/4
foo/bar
foo/bar/1
foo/bar/2
foo/bar/3
foo/bar/4
foo/bar/5
$ cd foo/
$ target="/tmp/target"; find . -type f | while read line; do outbn="$(basename "$line")"; while true; do if [[ -e "$target/$outbn" ]]; then outbn="z-$outbn"; else break; fi; done; cp "$line" "$target/$outbn"; done

然后

$ find $target
/tmp/target
/tmp/target/1
/tmp/target/2
/tmp/target/3
/tmp/target/4
/tmp/target/5
/tmp/target/z-1
/tmp/target/z-2
/tmp/target/z-3
/tmp/target/z-4

答案 1 :(得分:3)

我假设我可以将a/b/c.txt重命名为a-b-c.txt(即:顶层目录中不存在此类文件)。然后你可以:

 #copy all the files in the top directory
 for i in $(find . -type 'f' ); do
     cp $i $(echo $i | sed -e 's#./##' | tr / - );
 done

#remove subdirectories
find . -type 'd' | egrep -v "^.$" | xargs rm -r 

当然,您应该在尝试此类操作之前备份文件。

答案 2 :(得分:1)

此单线程序会将bar子文件夹中的所有文件复制到当前的directtory,其名称以bar-开头。

for i in bar/*; do cp "$i" "${i/\//-}"; done