我在/ home /中有大约200个目录。 问题是它们都以这种方式存在:
/家庭/ {}用户/主目录/
虽然它应该是:
/家庭/ {}用户/
用什么命令我可以批量移动每个用户的homedir一个目录的所有内容?
谢谢您的帮助。
这可能是不同的,这取决于你的shell,但假设bash:
for a in $(find /home -maxdepth 1 -type d); do mv $a/homedir/* $a/; rmdir $a/homedir; done
如果要保留每个文件夹中的空白homedir ,请分别运行find命令以validation列表是否为预期,然后再运行完整命令并除去rmdir部分。
除非你超出命令行长度,否则应该使用mv /home/*/* /home 。 请注意,如果您在/home/user文件也将被移至/home 。
将homedir内容移到目录中:
cd /home for i in */homedir; do /bin/mv $i/* $i/.. && /bin/rmdir $i; done
这是一个更偏执的脚本,避免所有的用户名(使用“@@@”为tmp目录),保留“mv $ a / homedir / *”丢弃的点文件,如果@@@ dir不一致则停止,并不应该有一个命令长度的问题。 其余的弱点是病态用户名。
cd /home ls -1 | while read user ; do # allow many user dirs without imploding [ -d @@@ ] && { echo tmp already present, aborting 1>&2 ; exit 1 ; } mv $user @@@ mv @@@/homedir $user rmdir @@@ || { echo tmp dir for $user not empty, aborting 1>&2 ; exit 2 ; } done
如果整个per-directory命令都被放在-exec中,find()方法是一个不错的select,如下所示:
cd /home && find -name . -o -type d -prune -print \ -exec mv '{}' @@@ ';' \ -exec mv @@@/homedir '{}' ';' \ -exec rmdir @@@ ';'
尝试像"for f in $(find ....)"是脆弱的,因为shell将首先扩展整个命令行。 这里显示的查找取决于通过甚至在string中查找扩展{},我不知道所有的支持。
甚至
cd /home && find -name . -o -type d -prune -print -exec \ sh -c 'mv {} @@@ && mv @@@/homedir {} && rmdir @@@' ';'
testing:
mkdir -p {fred,jan,alice}/homedir touch {fred,jan,alice}/homedir/.dotstuff touch {fred,jan,alice}/homedir/stuff
让一个撕裂(减去“CD /家”),看看它是如何做的。 在这里似乎都工作得很好。
SmallClanger的解决scheme可以改变,以便空白不成问题。 诀窍是改变Bash的内部字段分隔符,这是一个variablescallend IFS,通常包含一个空白和一个换行符,只是包含一个换行符。 如:
IFS=$'\n'
这会将IFS更改为当前shell的换行符。
之后,你可以运行SmallClanger的命令,或类似的东西:
for item in $(find ./homedir -mindepth 1 -maxdepth 1 -type d); do echo " --> \"$item\"" >&2 mv "$item" . done
这假设你的工作目录是“/ home / {user}”。
您可以在第一次尝试时省略“mv”行来查看$ item包含的内容。 如果看起来不错,用“mv”运行。 不要忘记“$ item”周围的双引号。
这样,如果任何文件或文件夹path包含换行符,则只会遇到问题,我认为这些换行符比包含空格符号更为不寻常。
有关内部字段分隔符的一些信息: Bash:内部variables
我也认为你可以让“find”程序把它的结果用NUL分隔开来。 如果可以将IFS设置为NUL,那么几乎任何事情都应该放在安全的一边,因为通常NUL不是大多数文件系统中文件/目录的允许代码点。 不过,我从来没有尝试过这个。
我会简单
cd /home/user/ mv homedir/* .