Bash shell 脚本:递归地 cat 文件夹中的 TXT 文件

Bash shell 脚本:递归地 cat 文件夹中的 TXT 文件

我有一个文件目录,其结构如下:

./DIR01/2019-01-01/Log.txt
./DIR01/2019-01-01/Log.txt.1
./DIR01/2019-01-02/Log.txt
./DIR01/2019-01-03/Log.txt
./DIR01/2019-01-03/Log.txt.1
...
./DIR02/2019-01-01/Log.txt
./DIR02/2019-01-01/Log.txt.1
...
./DIR03/2019-01-01/Log.txt

...等等。每个DIRxx目录都有许多按日期命名的子目录,这些子目录本身有许多需要连接的日志文件。要连接的文本文件数量各不相同,但理论上最多可以有 5 个。我希望看到对日期目录中的每组文件执行以下命令:

cd ./DIR01/2019-01-01/
cat Log.txt.4 Log.txt.3 Log.txt.2 Log.txt.1 Log.txt > ../../Log.txt_2019-01-01_DIR01.txt

(我理解上述命令会给出某些文件不存在的错误,但cat无论如何它都会按照我的需要执行)除了cd进入每个目录并运行上述cat命令之外,我怎样才能将其编写成 Bash shell 脚本?

答案1

与 Linux 一样,有几种可能的方法可以完成您的要求。

例如,使用 bash 的 glob 扩展在所有文件夹上运行脚本:

for dir in */* ; do                             # iterate through all 2nd-level subdirectories 
    if [ -d "$dir" ] ; then                     # only run on folders
        cat $dir/Log.txt* > Log.txt_${dir////_} # that mess of slashes replaces them with underscores in the filename
    fi
done

或者,您可以使用 find:

for dir in $(find -mindepth 2 -maxdepth 2 -type d)
    cat $dir/Log.txt* > Log.txt_${dir////_}
done

或者可能还有其他多种解决方案。

答案2

谢谢,但我找到的解决方案堆栈溢出是使用下面的代码:

for dir in DIR*/*; do 
    date=${dir##*/}; 
    dirname=${dir%%/*}; 
    cat $dir/Log.txt.{5..1} $dir/Log.txt > Log.txt_"${date}"_"${dirname}".txt; 
done

这将以相反的顺序连接文件,这正是我真正需要做的(如果这不清楚,请原谅)。

相关内容