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. 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:
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 cding into each directory and running the above cat command, how can I script this into a Bash shell script?
2 Answers
As usual for Linux, there are several possible ways of doing what you ask for.
For example, using bash's glob extension to run a script on all of the folders:
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
doneAlternatively, you could use find:
for dir in $(find -mindepth 2 -maxdepth 2 -type d) cat $dir/Log.txt* > Log.txt_${dir////_}
doneOr probably any number of other solutions.
Thanks, but the solution I found on StackOverflow was to use the below code:
for dir in DIR*/*; do date=${dir##*/}; dirname=${dir%%/*}; cat $dir/Log.txt.{5..1} $dir/Log.txt > Log.txt_"${date}"_"${dirname}".txt;
doneThis will concatenate the files in reverse order, which is what I actually need done (sorry if this wasn't clear).