假设更多用户的tmp
主目录中有一个目录。我想重命名tmp
每个用户主目录中的每个目录。最简单的方法是什么?
像这样的东西:
sudo mv /home/*/tmp /home/*/temp
不行。
像这样的东西:
for dir in /home/*; do
if [ -d $dir/tmp ]; then
mv $dir/tmp $dir/temp
fi
done
似乎太多了。
答案1
Perl 附带了一个rename(1)
安装在大多数 Linux 系统上的命令。在基于 Debian 的系统上,/usr/bin
对于这种情况,您可以像这样使用它:
$ rename 's/tmp$/temp/' /home/*/tmp
第一个参数是一个 perl 表达式,它作用于生成新名称的后续参数。然后根据该表达式的结果对每个进行重命名。
如果主目录已经有一个名为 的文件/目录temp
,您只会收到该目录的错误并rename
继续:
/home/c/tmp not renamed: /home/c/temp already exists
您可以先使用该-n
标志运行它,看看重命名会做什么,而无需实际执行它,并确保一切看起来都正确。然后放下它-n
,让它完成它的工作。
答案2
sudo find /home -maxdepth 2 -type d -name 'tmp' -execdir mv {} temp \;
此处,maxdepth
确保您仅查找当前目录中的最多两层。并且,execdir
指定将通过更改到找到的文件所在的位置来执行后续命令。
答案3
我能想到的缩短问题中第二个选项的唯一方法是:
for dir in /home/*;do
[ -d $dir/tmp ] && mv -n $dir/t{,e}mp
done
但这在一定程度上降低了可读性。请注意,t{,e}mp
被 shell 扩展为两个单词tmp
和temp
。因此命令行将扩展为mv <contents of $dir>/tmp <contents of $dir>/temp
.一般来说,shell 扩展prefix_{a,b,c}_suffix
为prefix_a_suffix prefix_b_suffix prefix_c_suffix
.空位置(例如 in 中的第一个位置){,e}
将扩展为空字符串。
您还可以执行类似的操作perl
:
perl -e '
@a=grep {-d} glob "/home/*/tmp";
map { rename $_ => $_=~ s/tmp\Z/temp" } @a
'
但我仍然认为你的原始版本已经足够好了。
编辑
添加了-n
开关mv
以保证它不会崩溃,$dir/temp
如果它存在,如 Michael Kjörling 对问题的评论中所述。 Perl 版本将要temp
如果存在则破坏。
答案4
生成移动语句并一次性评估它们:
ls -d /home/*/tmp | sed 's/.*t/mv &mp &e/' | sh -xv