[英]move files that have the same name of the file they contain
Someone very clever (feel irony?) has extracted more than 6000 archives in their own directories, but sometimes the archive contain one file: the same name of the directory it contains. 一个非常聪明的人(感到讽刺?)已经在自己的目录中提取了6000多个档案,但是有时档案包含一个文件:与该目录的名称相同。
Example: 例:
mydir(0001)/mydir(0001).txt
mydir(ZREZ)/mydir(ZREZ).txt
mydir(AAEZ)/mydir(AAREZ).txt
mydir(AAEZ)/otherfile.txt
mydir(QQQQ)/mydir(QQQQ).txt
...
Is there a fast way (Unix shell) to compare the file (if there's only one file) and the directory where it's in, and if it's the same (without the extension), move it one directory above and remove the (now empty) directory? 有没有一种快速的方法(Unix shell)来比较文件(如果只有一个文件)和文件所在的目录,如果文件相同(没有扩展名),则将其移至上方一个目录并删除(现在为空)目录?
So I should get: 所以我应该得到:
mydir(0001).txt
mydir(ZREZ).txt
mydir(AAEZ)/mydir(AAREZ).txt
mydir(AAEZ)/otherfile.txt
mydir(QQQQ).txt
...
You can use a script like this from the parent directory of all those 6000 directories/files: 您可以从所有这6000个目录/文件的父目录中使用如下脚本:
while IFS= read -d '' -r d; do
n=$(find "$d" -maxdepth 1 -type f -exec echo . \; | wc -l)
f="${d}/${d}.txt"
[[ $n -eq 1 && -f "$f" ]] && mv "$f" "$d/../" && rmdir "$d"
done < <(find . -type d ! -name '.' -print0)
This should do the trick. 这应该可以解决问题。 A bit simpler than anubhava's script, but still careful about only moving files and removing dirs if that's the only content.
比anubhava的脚本简单一些,但是如果唯一的内容,那就还是只移动文件并删除目录。
for x in *; do
if [[ $(find "$x" | sed 1d | head -n2) == "$x/$x.txt" ]]; then
mv "$x/$x.txt" . && rmdir "$x"
fi
done
You can cut-n-paste this to the command line in the parent dir. 您可以将其剪切-n-粘贴到父目录的命令行中。 It loops over all files in that dir (
for x in *
) and if any of them is itself a directory containing only the single file $x/$x.txt
then it will move the file and remove the directory. 它循环遍历该目录中的所有文件(
for x in *
),如果其中任何一个文件本身是仅包含单个文件$x/$x.txt
的目录,则它将移动文件并删除目录。
Here's my script, based on Anubhava's first answer. 这是我的脚本,基于Anubhava的第一个答案。 Sorry for the beginner's style:
对不起初学者的风格:
#!/bin/bash
# loop & print a folder recusively,
folder_recurse() {
for i in "$1"/*;do
if [ -d "$i" ];then
n=$(find "$i" -maxdepth 1 -exec echo . \; | wc -l)
d=$(readlink -f "${i}")
g=$d"/"$(basename "$i")".epub"
if [[ $n -eq 2 && -f "$g" ]]; then
echo "Doing: $i"
mv "$g" "$d/.."
rmdir "$d"
fi
folder_recurse "$i"
done
}
# try get path from param
path=""
if [ -d "$1" ]; then
path=$1;
else
path="/tmp"
fi
echo "base path: $path"
folder_recurse $path
You can do it with a one-liner within the parent directory: 您可以在父目录中使用单行代码来执行此操作:
for i in */*; do [ -f "${i%/*}/${i%/*}.txt" ] && mv "$i" . && rm -d "${i%/*}"; done
Since there has been interest in a solution that function equally on BSD where there is no rm -d
, the same can be accomplished with: 由于人们一直对在
rm -d
无的BSD上同样起作用的解决方案感兴趣,因此可以使用以下方法实现相同的目的:
for i in */*; do [ -f "${i%/*}/${i%/*}.txt" ] && mv "$i" . && [ -z "$(ls -A "${i%/*}")" ] && rm -r "${i%/*}"; done
Which, following the mv
check whether the remaining directory is empty, and if so, then removes the directory, otherwise leaving the directory unchanged. 然后,在
mv
检查其余目录是否为空,如果是,则删除目录,否则保持目录不变。
output: 输出:
drwxr-xr-x 2 david david 4096 Aug 25 16:20 mydir(AAEZ)
-rw-r--r-- 1 david david 0 Aug 25 16:20 mydir(0001).txt
-rw-r--r-- 1 david david 0 Aug 25 16:20 mydir(QQQQ).txt
-rw-r--r-- 1 david david 0 Aug 25 16:20 mydir(ZREZ).txt
mydir\(AAEZ\)/
-rw-r--r-- 1 david david 0 Aug 25 16:20 mydir(AAREZ).txt
-rw-r--r-- 1 david david 0 Aug 25 16:20 otherfile.txt
If needed, you can also test that the directory is empty after moving the file -- before deleting the directory. 如果需要,您还可以在移动文件后(删除目录之前)测试目录是否为空。 Shown
所示
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.