好吧,我认为这是可能的,但我不太明白。情况就是这样。
一个文件夹包含我的机器人上所有进程的日志文件。结构看起来有点像这样:
$ ls -lrt
total 8
drwxrwxr-x 2 per per 4096 nov 3 12:46 launch01
-rw-rw-r-- 1 per per 0 nov 3 12:47 camera112.log
-rw-rw-r-- 1 per per 0 nov 3 12:47 motors121.log
-rw-rw-r-- 1 per per 0 nov 3 12:47 lidar111.log
drwxrwxr-x 2 per per 4096 nov 3 12:49 launch02
-rw-rw-r-- 1 per per 0 nov 3 12:49 motors122.log
-rw-rw-r-- 1 per per 0 nov 3 12:49 lidar211.log
-rw-rw-r-- 1 per per 0 nov 3 12:49 camera113.log
文件camera112.log
和motors121.log
与lidar111.log
文件夹中的日志相关联launch01
。我想编写一个脚本来获取属于特定启动的所有文件并将它们打包到一个 tarball 中。由于时间戳可能会因文件而略有变化,并且文件中的数字几乎相关,因此我认为收集所有相关文件的最佳方法是获取以下launch01
(含)、直到列表中的下一个目录的所有文件(独家的)。文件的数量可能有所不同,时间戳和名称也可能有所不同。一致的是文件夹,然后是一堆文件,然后是下一个文件夹,然后是文件,等等。最终,我想轻松获得最新的日志集。
不确定这里的方法。有什么想法如何解决这个问题吗?
澄清:
- 文件数量可能会有所不同。
- 确切的时间戳不可靠(如上所述,文件夹
launch01
与 不同camera112.log
),但相对时间戳工作正常。例如,如果我可以将提供的列表中从launch01
(包含)到(不包含)的所有文件打包,那就太好了。launch02
ls -lrt
答案1
使用您的输入将任务分成多个块
drwxrwxr-x 2 per per 4096 nov 3 12:46 launch01
-rw-rw-r-- 1 per per 0 nov 3 12:47 camera112.log
-rw-rw-r-- 1 per per 0 nov 3 12:47 motors121.log
-rw-rw-r-- 1 per per 0 nov 3 12:47 lidar111.log
drwxrwxr-x 2 per per 4096 nov 3 12:49 launch02
-rw-rw-r-- 1 per per 0 nov 3 12:49 motors122.log
-rw-rw-r-- 1 per per 0 nov 3 12:49 lidar211.log
-rw-rw-r-- 1 per per 0 nov 3 12:49 camera113.log
仅创建文件名的“有序”列表
使用其中之一:
ls -lrt | tr -s ' ' | cut -d' ' -f9
ls -lrt | awk '{print $9}'
给出:
launch01
camera112.log
motors121.log
lidar111.log
launch02
motors122.log
lidar211.log
camera113.log
将列表分成几个部分
修改这个回答到根据分隔符将一个文件拆分为多个文件,创建一个名为的文件,awk_pattern
其中包含以下内容:
BEGIN{ fn = "part1.txt"; n = 1 }
{
if (substr($0,1,6) == "launch") {
close (fn)
n++
fn = "part" n ".txt"
}
print > fn
}
然后运行
ls -lrt | awk '{print $9}' | awk -f awk_pattern
给出所需的输出:
part1.txt
launch01
进而
part2.txt
launch01
camera112.log
motors121.log
lidar111.log
part3.txt
launch02
motors122.log
lidar211.log
camera113.log
虽然第一个文件 ( part1.txt
) 应该被丢弃,因为它只包含一行......
rm part1.txt
tar 各部分的内容
tar -c -v -z -T part2.txt -f part2.tgz
循环遍历 tar 文件
for part_file in $(ls part*)
do
tar_file = ${part_file%.*}
# tar_file = basename ${part_file} .txt
tar -c -v -z -T ${part_file} -f ${tar_file}.tgz
done
这应该给
part1.tgz
part2.tgz
part3.tgz
再次,part1.tgz
应该被丢弃:
rm part1.tgz
把它们放在一起
#!/bin/bash
ls -lrt | awk '{print $9}' | awk -f awk_pattern
for part_file in $(ls part*)
do
tar_file = ${part_file%.*}
tar -c -v -z -T ${part_file} -f ${tar_file}.tgz
done
rm part1.txt
rm part1.tgz
作为一个脚本(包含 awk 模式)
#!/bin/bash
ls -lrt | awk '{print $9}' | awk 'BEGIN{ fn = "part1.txt"; n = 1 }
{
if (substr($0,1,6) == "launch") {
close (fn)
n++
fn = "part" n ".txt"
}
print > fn
}'
for part_file in $(ls part*)
do
tar_file = ${part_file%.*}
tar -c -v -z -T ${part_file} -f ${tar_file}.tgz
done
rm part1.txt
rm part1.tgz
这个(希望如此)应该工作,尽管我只测试了前两个步骤,即直到 tar 部分,因为我没有要压缩的文件。
可能的改进:
后期处理:删除
part*.txt
文件(rm part*.txt
)后期处理:压缩后删除日志文件 (
rm *.log
)后期处理: 压缩后删除目录 (
rm -R -- */
)看到这个回答到如何从目录中删除所有子目录?。
防止 awk 产生无用的
part1.txt
文件将 tar 文件保存在其他位置 (
... -f ${tar_path}/${tar_file}.tgz
)不要使用中间
part*.txt
文件。