I need to concat multiple files to a single file in reverse order.
The order of lines in the files should not be changed.
For example:
file 1.txt
1
2
file 2.txt
3
4
The expected result:
result.txt
3
4
1
2
These command do not work as expected:
tac *.txt > result.txt
just reverses the order of lines in the files and concat the files in ordinal order. ( 2 1 4 3
)
cat $(ls -r) > result.txt
or ls -r | xargs cat > result.txt
ls -r | xargs cat > result.txt
do not work if filenames have a space character:
cat: file: No such file or directory
cat: 2.txt: No such file or directory
cat: file: No such file or directory
cat: 1.txt: No such file or directory
The problem is that while ls -r
returns 'file 2.txt' 'file 1.txt'
, but echo $(ls -r)
returns file 2.txt file 1.txt
that looks like four files for cat
.
Great - so first list the filenames , then reverse their order, then cat them.
find . -type f -name '*.txt' | sort -r | xargs -d'\n' cat
And similar with filename expansion, that is sorted by itself:
printf "%s\n" *.txt | tac | xargs -d'\n' cat
To be fullproff against newlines in filenames, use zero separated streams - printf "%s\0"
find.. -print0
xargs -0
tac -s ''
.
Remember do not parse ls .
Try this (recursive) function:
function revcat
{
(( $# == 0 )) && return 0
revcat "${@:2}"
cat -- "$1"
}
Example usage:
revcat *.txt
Since there is no short one line command that can be easily be typed from memory. It makes sense to create a function and put it into .bashrc
file.
pjh's recursive function works inappropriate slow. So I wrote this one:
function revcat {
for item in "$@"; do
echo "$item";
done | tac | xargs -d"\n" cat;
}
It works like cat
, but with the expected, reversed, file concatenation order.
For example: revcat *.txt > out.txt
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.