简体   繁体   English

如何用BASH中的另一个文件中的相应行填充一个文件中的空行?

[英]How to fill empty lines from one file with corresponding lines from another file, in BASH?

I have two files, file1.txt and file2.txt . 我有两个文件, file1.txtfile2.txt Each has an identical number of lines, but some of the lines in file1.txt are empty. 每个都有相同数量的行,但file1.txt中的一些行是空的。 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 . 我需要将这些文件组合在一起,以便file1.txt中的空行用file2.txt中的行(相同行号)中的数据file2.txt The result in file3.txt would look like this: file3.txt的结果如下所示:

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. 到目前为止我能做的最好的事情是创建一个while read -r line循环,创建一个计算while循环循环次数的计数器,然后使用if-conditional来检查$line是否为空,然后使用cut to根据计数器上的数字从file2.txt获取行号。 This method seems really inefficient. 这种方法似乎效率很低。

  • Sometimes file2.txt might contain some empty lines. 有时file2.txt可能包含一些空行。 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 . 如果file1.txt有一个空行而file2.txt在同一个地方也有一个空行,则结果是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处理这些文件的方法:

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 首先,它使用记录号作为索引将file2每个数据存储在数组a
Then it prints file1 , bit it thest if file1 contains data for each record 然后它打印file1 ,如果file1包含每个记录的数据,则将其写入
If there is data for this record, then use it, if not get one from file2 如果有此记录的数据,则使用它,如果没有从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. 这将删除位于行开头的选项卡(从file1中丢失的选项卡),然后获取第一列。

(For OSX, \\t doesn't work in sed, so to get the TAB character, you type ctrl-V then Tab) (对于OSX, \\t在sed中不起作用,因此要获取TAB字符,请键入ctrl-V然后键入Tab)

Here is a Bash only solution. 这是一个仅限Bash的解决方案。

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

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

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