我需要编写一个简单的程序来遍历带有子文件夹的文件夹并删除该文件夹下每个子文件夹中的最后一个文件
I need to write a simple program that goes through a folder with subfolders and deletes the last file in each subfolder beneath the folder
我搜索了整个网站,没有找到我需要的东西,所以我决定提出自己的问题。
我正在使用 linux,试图找出一种方法来使用 find、awk、rm 等工具来完成我所描述的事情;但是至今想不出办法
一些背景知识,
- 文件以整齐的字母顺序重命名。没有白space.
- 子文件夹也是这样命名的。
- 当我说最后一个文件时,我指的是按字母顺序排序的最后一个文件。
- 每个子文件夹中的文件数量不一样。一些子文件夹有 56 个文件,而另一些子文件夹甚至没有达到两位数。所以我不能执行这样一个方便的命令:
rm ./folder-*/020.jpg
如果所有子文件夹中的文件数量相同,我就能做到。
为了说明目录,应该是这样的
./original-folder
./original-folder/subfolder-001/001.jpg
./original-folder/subfolder-001/002.jpg
./original-folder/subfolder-001/003.jpg
./original-folder/subfolder-002/001.jpg
./original-folder/subfolder-002/002.jpg
./original-folder/subfolder-003/001.jpg
等等。
我希望它基本上看起来像这样
./original-folder
./original-folder/subfolder-001/001.jpg
./original-folder/subfolder-001/002.jpg
./original-folder/subfolder-002/001.jpg
./original-folder/subfolder-003/001.jpg
注意最后一个文件比之前少了一个。
我的解决方案是找到一种方法,每次程序进入一个新文件夹时都启动一个列表,然后为 rm 命令借用该列表的最后一项,但我完全不知道如何在其中执行此操作bash 或任何东西。
感觉我需要一种功能齐全的编程语言来做到这一点。
鉴于您的输入文件以可排序的方式命名并且不包含任何空格,如您问题中的示例所示:
$ cat tst.sh
#!/usr/bin/env bash
find ./original-folder -type f |
sort |
awk '
{
dir = [=10=]
sub("/[^/]+$","",dir)
}
dir != prev {
prt()
numFiles = 0
prev = dir
}
{ files[++numFiles] = [=10=] }
END { prt() }
function prt( fileNr, endNr) {
endNr = numFiles - ( numFiles == 1 ? 0 : 1 )
for ( fileNr=1; fileNr <= endNr; fileNr++ ) {
print files[fileNr]
}
}
' |
xargs -I {} echo rm -- '{}'
$ ./tst.sh
rm -- ./original-folder/subfolder-001/001.jpg
rm -- ./original-folder/subfolder-001/002.jpg
rm -- ./original-folder/subfolder-002/001.jpg
rm -- ./original-folder/subfolder-003/001.jpg
一旦您初步测试并对结果感到满意,请删除 echo
。 sort
可能不是必需的,具体取决于 find
输出结果的顺序,但它不会造成伤害。
假设你可以在这个方法对我有用的目录中创建文件:
#!/bin/bash
originalFolder=/path/to/your/directory/containing/orignal-folder
ls $originalFolder > folder_list.txt
while read -r line; do
ls -r "$originalFolder/$line" > file_list.txt
fileLength=$(wc -l < file_list.txt)
if [ "$fileLength" -gt 1 ]
then
rmFile=$(head -n 1 file_list.txt)
rm "$originalFolder/$line/$rmFile"
fi
done < folder_list.txt
我搜索了整个网站,没有找到我需要的东西,所以我决定提出自己的问题。
我正在使用 linux,试图找出一种方法来使用 find、awk、rm 等工具来完成我所描述的事情;但是至今想不出办法
一些背景知识,
- 文件以整齐的字母顺序重命名。没有白space.
- 子文件夹也是这样命名的。
- 当我说最后一个文件时,我指的是按字母顺序排序的最后一个文件。
- 每个子文件夹中的文件数量不一样。一些子文件夹有 56 个文件,而另一些子文件夹甚至没有达到两位数。所以我不能执行这样一个方便的命令:
rm ./folder-*/020.jpg
如果所有子文件夹中的文件数量相同,我就能做到。
为了说明目录,应该是这样的
./original-folder
./original-folder/subfolder-001/001.jpg
./original-folder/subfolder-001/002.jpg
./original-folder/subfolder-001/003.jpg
./original-folder/subfolder-002/001.jpg
./original-folder/subfolder-002/002.jpg
./original-folder/subfolder-003/001.jpg
等等。 我希望它基本上看起来像这样
./original-folder
./original-folder/subfolder-001/001.jpg
./original-folder/subfolder-001/002.jpg
./original-folder/subfolder-002/001.jpg
./original-folder/subfolder-003/001.jpg
注意最后一个文件比之前少了一个。
我的解决方案是找到一种方法,每次程序进入一个新文件夹时都启动一个列表,然后为 rm 命令借用该列表的最后一项,但我完全不知道如何在其中执行此操作bash 或任何东西。
感觉我需要一种功能齐全的编程语言来做到这一点。
鉴于您的输入文件以可排序的方式命名并且不包含任何空格,如您问题中的示例所示:
$ cat tst.sh
#!/usr/bin/env bash
find ./original-folder -type f |
sort |
awk '
{
dir = [=10=]
sub("/[^/]+$","",dir)
}
dir != prev {
prt()
numFiles = 0
prev = dir
}
{ files[++numFiles] = [=10=] }
END { prt() }
function prt( fileNr, endNr) {
endNr = numFiles - ( numFiles == 1 ? 0 : 1 )
for ( fileNr=1; fileNr <= endNr; fileNr++ ) {
print files[fileNr]
}
}
' |
xargs -I {} echo rm -- '{}'
$ ./tst.sh
rm -- ./original-folder/subfolder-001/001.jpg
rm -- ./original-folder/subfolder-001/002.jpg
rm -- ./original-folder/subfolder-002/001.jpg
rm -- ./original-folder/subfolder-003/001.jpg
一旦您初步测试并对结果感到满意,请删除 echo
。 sort
可能不是必需的,具体取决于 find
输出结果的顺序,但它不会造成伤害。
假设你可以在这个方法对我有用的目录中创建文件:
#!/bin/bash
originalFolder=/path/to/your/directory/containing/orignal-folder
ls $originalFolder > folder_list.txt
while read -r line; do
ls -r "$originalFolder/$line" > file_list.txt
fileLength=$(wc -l < file_list.txt)
if [ "$fileLength" -gt 1 ]
then
rmFile=$(head -n 1 file_list.txt)
rm "$originalFolder/$line/$rmFile"
fi
done < folder_list.txt