I have two files, file1.txt
and file2.txt
. Each has an identical number of lines, but some of the lines in file1.txt
are empty. This is easiest to see when the content of the two files is displayed in parallel:
file1.txt file2.txt
cat bear
fish eagle
spider leopard
snail
catfish rainbow trout
snake
koala
rabbit fish
I need to assemble these files together, such that the empty lines in file1.txt
are filled with the data found in the lines (of the same line number) from file2.txt
. The result in file3.txt
would look like this:
cat
fish
spider
snail
catfish
snake
koala
rabbit
The best I can do so far, is create a while read -r line
loop, create a counter that counts how many times the while loop has looped, then use an if-conditional to check if $line
is empty, then use cut
to obtain the line number from file2.txt
according to the number on the counter. This method seems really inefficient.
file2.txt
might contain some empty lines. If file1.txt
has an empty line and file2.txt
also has an empty line in the same place, the result is an empty line in file3.txt
. How can I fill the empty lines in one file with corresponding lines from another file?
paste file1.txt file2.txt | awk -F '\t' '$1 { print $1 ; next } { print $2 }'
Here is the way to handle these files with awk
:
awk 'FNR==NR {a[NR]=$0;next} {print (NF?$0:a[FNR])}' file2 file1
cat
fish
spider
snail
catfish
snake
koala
rabbit
First it store every data of the file2
in array a
using record number as index
Then it prints file1
, bit it thest if file1
contains data for each record
If there is data for this record, then use it, if not get one from file2
一个与getline(在这种情况下无害):
awk '{getline p<f; print NF?$0:p; p=x}' f=file2 file1
Just for fun:
paste file1.txt file2.txt | sed -E 's/^ //g' | cut -f1
This deletes tabs that are at the beginning of a line (those missing from file1) and then takes the first column.
(For OSX, \\t
doesn't work in sed, so to get the TAB character, you type ctrl-V then Tab)
Here is a Bash only solution.
for i in 1 2; do
while read line; do
if [ $i -eq 1 ]; then
arr1+=("$line")
else
arr2+=("$line")
fi
done < file${i}.txt
done
for r in ${!arr1[@]}; do
if [[ -n ${arr1[$r]} ]]; then
echo ${arr1[$r]}
else
echo ${arr2[$r]}
fi
done > file3.txt
没有awk的解决方案:
paste -d"#" file1 file2 | sed 's/^#\(.*\)/\1/' | cut -d"#" -f1
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.