awk打开多个文件的方法

本文引自:http://www.cnblogs.com/Berryxiong/p/6209324.html

1、当awk读取的文件只有两个的时候,比较常用的有三种方法
(1)awk 'NR==FNR{...}NR>FNR{...}' file1 file2

(2)awk 'NR==FNR{...}NR!=FNR{...}' file1 file2
(3)awk 'NR==FNR{...;next}{...}' file1 file2

next表示下一个命令不被执行

2、当awk处理的文件超过两个时,显然上面那种方法就不适用了。因为读第3个文件或以上时,也满足NR>FNR (NR!=FNR),显然无法区分开来。
所以就要用到更通用的方法了:
(1)ARGIND 当前被处理参数标志: awk 'ARGIND==1{...}ARGIND==2{...}ARGIND==3{...}... ' file1 file2 file3 ...
(2)ARGV 命令行参数数组: awk 'FILENAME==ARGV[1]{...}FILENAME==ARGV[2]{...}FILENAME==ARGV[3]{...}...' file1 file2 file3 ... 
(3)把文件名直接加入判断: awk 'FILENAME=="file1"{...}FILENAME=="file2"{...}FILENAME=="file3"{...}...' file1 file2 file3 ...

举例说明,这个例子在面试的时候问过。

a.txt中有一列:


B
C
D
E
b.txt中有两列:

A hello world
A good morning
B what
C sad 
D interview someone
D feeling bad
E not so good
E want to be happy
F fail to pass the exam
G good result
则打印出b.txt中的行,满足b.txt中第一列等于a.txt的第一列。

#! /usr/bin/ksh

print "Method1:########"
awk 'ARGIND==1{test[NR]=$1}
    ARGIND==2{for(i in test){if(test[i]==$1){print $0}}}' a.txt b.txt

print "\nMethod2:########"
#the '{" must at the same line of the NR!=FNR
gawk 'NR==FNR{test[NR]=$1}
    NR!=FNR{ 
        for( i in test)
        {
            if(test[i]==$1)
                print $0
        }
           }' a.txt b.txt

print "\nMethod3:########"
gawk 'NR==FNR{test[NR]=$1}
        NR>FNR{ 
                for( i in test)
                {
                        if(test[i]==$1)
                                print $0
                }
        }' a.txt b.txt

print "\nMethod4:########"
gawk 'NR==FNR{test[NR]=$1;next}
        {
                for( i in test)
                {
                        if(test[i]==$1)
                                print $0
                }
        }' a.txt b.txt

print "\nMethod5:########"
gawk 'FILENAME==ARGV[1]{test[NR]=$1}
        FILENAME==ARGV[2]{
                for( i in test)
                {
                        if(test[i]==$1)
                                print $0
                }
        }' a.txt b.txt

print "\nMethod6:########"
gawk 'FILENAME=="a.txt"{test[NR]=$1}
        FILENAME=="b.txt"{
                for( i in test)
                {
                        if(test[i]==$1)
                                print $0
                }
        }' a.txt b.txt

输出结果为:

Method1:########
A hello world
A good morning
B what
C sad 
D interview someone
D feeling bad
E not so good
E want to be happy

Method2:########
A hello world
A good morning
B what
C sad 
D interview someone
D feeling bad
E not so good
E want to be happy

Method3:########
A hello world
A good morning
B what
C sad 
D interview someone
D feeling bad
E not so good
E want to be happy

Method4:########
A hello world
A good morning
B what
C sad 
D interview someone
D feeling bad
E not so good
E want to be happy

Method5:########
A hello world
A good morning
B what
C sad 
D interview someone
D feeling bad
E not so good
E want to be happy

Method6:########
A hello world
A good morning
B what
C sad 
D interview someone
D feeling bad
E not so good
E want to be happy
<think>好的,用户想合并多个TSV文件为一个文本文件,使用Python、Pandas或者命令行工具。首先,我需要回忆一下相关的命令和方法。 对于命令行工具,最简单的方法可能是使用cat命令,因为TSV文件的结构相同的话,直接合并是可行的。比如在Linux或MacOS中,可以用cat *.tsv > merged.txt。但要注意的是,如果有表头的话,可能需要处理重复的标题行,这时候可以用sed或者awk来去掉多余的标题,只保留第一个文件的标题。例如,cat file1.tsv <(tail -n +2 file2.tsv) <(tail -n +2 file3.tsv) > merged.txt。不过用户可能不太熟悉这些命令的细节,需要详细说明。 然后是Python和Pandas的方法。使用Pandas的话,可以逐个读取每个TSV文件,合并后再保存。需要注意的是处理表头的问题,比如是否保留第一个文件的表头,后续文件跳过第一行。代码的大致结构应该是用glob获取所有文件,循环读取,使用pd.concat合并。但要确保列名一致,否则可能会有问题。此外,内存问题也要考虑,如果文件很大,可能需要分块处理,但用户的问题中没有提到文件大小,可能默认是中小型文件。 另外,还可以用纯Python的方式,不依赖Pandas。打开每个文件,逐行读取,如果是第一个文件就保留全部行,否则跳过第一行。这种方法对于大文件可能更高效,因为不会一次性加载到内存中。 用户可能的需求是简单高效地合并文件,可能需要比较不同方法的优缺点。比如命令行最快,但处理复杂情况需要更多技巧;Python方法灵活,适合自动化处理;Pandas适合需要数据处理的情况。 需要检查是否有遗漏的情况,比如文件编码问题,不同系统的路径差异,或者TSV文件中可能存在的格式不一致问题。但用户的问题中未提及这些,可能假设文件结构一致。 最后,生成相关问题,可能涉及如何处理不同结构的TSV文件,合并时去重,或者性能优化等。确保问题与主题相关,帮助用户深入理解。</think>### 合并多个TSV文件为单一文本文件方法 #### 1. **命令行工具(快速简单)** - **使用`cat`命令**(适用于Linux/MacOS或Windows WSL): ```bash # 合并所有TSV文件并保留第一个文件的表头 cat file1.tsv <(tail -n +2 file2.tsv) <(tail -n +2 file3.tsv) > merged.txt ``` - `tail -n +2` 用于跳过后续文件的表头[^1]。 - **使用`awk`处理复杂情况**: ```bash awk 'NR==1 || FNR!=1' *.tsv > merged.txt ``` - `NR==1`保留第一个文件的表头,`FNR!=1`跳过其他文件的表头[^2]。 #### 2. **Python(灵活可控)** - **使用纯Python逐行合并**: ```python import glob output_file = "merged.txt" with open(output_file, 'w') as out_f: for i, file in enumerate(glob.glob("*.tsv")): with open(file, 'r') as in_f: header = in_f.readline() if i == 0: out_f.write(header) for line in in_f: out_f.write(line) ``` #### 3. **Pandas(适合数据清洗)** - **合并并保留表头**: ```python import pandas as pd import glob files = glob.glob("*.tsv") df = pd.concat((pd.read_csv(f, sep='\t') for f in files), ignore_index=True) df.to_csv("merged.txt", sep='\t', index=False) ``` - 若需跳过后续文件的表头,可在`pd.read_csv`中添加`header=0`参数[^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值