简体   繁体   English

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

[英]Bash shell script: recursively cat TXT files in folders

I have a directory of files with a structure like below:我有一个文件目录,其结构如下:

./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

...and so on. ...等等。 Each DIRxx directory has a number of subdirectories named by date, which themselves have a number of log files that need to be concatenated.每个DIRxx目录都有许多按日期命名的子目录,这些子目录本身有许多需要连接的日志文件。 The number of text files to concatenate varies, but could theoretically could be as many as 5. I would like to see the following command performed for each set of files within the dated directories (note that the files must be concatenated in reverse order):要连接的文本文件的数量各不相同,但理论上可以多达 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

(I understand the above command will give an error that certain files do not exist, but the cat will do what I need of it anyways) Aside from cd ing into each directory and running the above cat command, how can I script this into a Bash shell script? (我知道上面的命令会给出某些文件不存在的错误,但无论如何cat都会做我需要的事情)除了cd进入每个目录并运行上面的cat命令之外,我如何将其编写成脚本Bash shell 脚本?

If you just want to concatenate all files in all subdirectories whose name starts with Log.txt , you could do something like this:如果您只想连接名称以Log.txt开头的所有子目录中的所有文件,您可以执行以下操作:

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

If you need the files in reverse numerical order, from 5 to 1 and then Log.txt , you can do this:如果您需要以相反的数字顺序(从 5 到 1 然后是Log.txt ,您可以这样做:

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

That will, as you mention in your question, complain for files that don't exist, but that's just a warning.正如您在问题中提到的,这将抱怨不存在的文件,但这只是一个警告。 If you don't want to see that, you can redirect error output (although that might cause you to miss legitimate error messages as well):如果您不想看到它,您可以重定向错误输出(尽管这也可能导致您错过合法的错误消息):

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

Not as comprehensive as the other, but quick and easy.不像其他的那么全面,但又快又容易。 Use find and sort your output however you like ( -zrn is --zero-terminated --reverse --numeric-sort ) then iterate over it with read .使用findsort你喜欢的输出( -zrn is --zero-terminated --reverse --numeric-sort )然后用read迭代它。

find . -type f -print0 |
sort -zrn |

while read -rd ''; do
    cat "$REPLY";
done >> log.txt

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM