我想编写一个脚本来“取消隐藏”某个目录内的所有文件和目录一气呵成,例如./unhide test
。
test/
├── sub1
│ └── .hiddenfile1
└── sub2
└── .hiddendir
├── .hiddendirsub
├── .hiddenfile2
└── not.hidden
期望的结果:
test/
├── sub1
│ └── hiddenfile1
└── sub2
└── hiddendir
├── hiddendirsub
├── hiddenfile2
└── not.hidden
我怎样才能做到这一点?
我对此还不熟悉,我一直在尝试使用 来寻找解决方案find
,但却停留在-exec
和rename
(或mv
)处,因为我仍然无法理解这种组合是如何工作的。:( 所以,如果这里有人能给出解决方案和详细解释,我将不胜感激。谢谢。
答案1
find
您可以按照如下方式进行操作:
find /path/to/test -depth -name ".*" -execdir rename -n 's|/\.|/|' {} +
如果它显示您想要删除的选项,这只会打印重命名操作-n
。
解释
-depth
– 允许find
从下到上进行处理,在文件父目录之前重命名文件-name ".*"
–find
搜索文件(一切皆文件) 以点开头 - 这里的点是文字,因为这不是一个正则表达式-execdir … +
–…
在匹配文件的目录中执行rename 's|/\.|/|' {}
– 将匹配文件路径(find
的占位符为{}
)中第一次出现的“/.”替换为“/”,本质上是从文件名开头删除点。
例如,rename 's|/\.|/|' ./.hiddenfile1
在您的情况下,这将被重命名为./hiddenfile1
。
示例运行
$ tree -a
.
├── sub1
│ └── .hiddenfile1
└── sub2
└── .hiddendir
├── .hiddendirsub
├── .hiddenfile2
└── not.hidden
$ find ~/test -depth -name ".*" -execdir rename 's|/\.|/|' {} +
$ tree -a
.
├── sub1
│ └── hiddenfile1
└── sub2
└── hiddendir
├── hiddendirsub
├── hiddenfile2
└── not.hidden
脚本中的用法
在脚本中,你可以简单地使用位置参数而不是路径,它可以是相对的,也可以是绝对的——只要记住正确引用:
#!/bin/bash
find "$1" -depth -name ".*" -execdir rename -n 's|/\.|/|' {} +
答案2
$ tree -a test
test
├── .alsohidden
├── sub1
│ └── .hiddenfile1
└── sub2
├── .hiddendirsub
├── .hiddenfile2
└── not.hidden
3 directories, 4 files
$ find test/ -depth -name ".*" -exec rename -n 's|(.*/)\.(.*)|$1$2|' {} +
rename(test/.alsohidden, test/alsohidden)
rename(test/sub2/.hiddendirsub, test/sub2/hiddendirsub)
rename(test/sub2/.hiddenfile2, test/sub2/hiddenfile2)
rename(test/sub1/.hiddenfile1, test/sub1/hiddenfile1)
find test/
路径以 开始test/
,从此路径递归搜索-depth
被盗甜点的答案- 似乎是个好主意-name ".*"
文件名以...开头.
-exec command {} +
跑步command
在找到的文件上构建一个参数列表。rename -n
不执行任何操作,仅显示将要执行的操作(-n
测试后删除以实际重命名)s|old|new|
old
用。。。来代替new
(.*/)\.(.*)
保存直到最后一个目录分隔符的所有字符/
,跳过文字.
,保存所有后续字符$1$2
打印保存的图案