使用grep提取列

时间:2016-09-17 20:45:42

标签: unix

我有一个包含> 100列的数据框,每列都标有唯一的字符串。第1列表示索引变量。我想使用基本的UNIX命令来使用grep提取索引列(第1列)+特定的列字符串。

例如,如果我的数据框如下所示:

Index  A  B  C...D  E  F
p1     1  7  4   2  5  6
p2     2  2  1   2  .  3
p3     3  3  1   5  6  1

我想使用一些命令来仅提取列" X"我将使用GREP指定,并显示第1列和第1列。列我grep' d。我知道我可以使用cut -f1 myfile作为第一位,但需要帮助每列grep。作为一个更具体的例子,如果我的grep短语是" B",我希望输出为:

Index  B
p1     7
p2     2
p3     3

我是UNIX新手,在类似的例子中找不到多少。任何帮助将不胜感激!!

3 个答案:

答案 0 :(得分:5)

首先找出查找列号的命令。

columnname=C
sed -n "1 s/${columnname}.*//p" datafile | sed 's/[^\t*]//g' | wc -c

知道号码后,请使用剪切

cut -f1,3 < datafile 

合并为一个命令

cut -f1,$(sed -n "1 s/${columnname}.*//p" datafile | 
   sed 's/[^\t*]//g' | wc -c) < datafile

完成了吗?不,当一个标头可以是另一个标头的子字符串时,您应该改进第一个sed命令:在匹配中包含标签并将标签放回替换字符串中。

答案 1 :(得分:4)

你需要使用awk:

from subprocess import Popen
import os

def journal():
    with open('Invalid_names_file', 'w') as Invalid_names_file:
        Popen('journalctl -u sshd.service --no-pager --since -168hours\
                --until today | grep Invalid', stdout=Invalid_names_file,\
                universal_newlines=True, bufsize=1, shell=True)
        if os.stat('Invalid_names_file').st_size == 0:
            Popen('journalctl -u ssh.service --no-pager --since -168hours\
                    --until today | grep Invalid', stdout=Invalid_names_file,\
                    universal_newlines=True, bufsize=1, shell=True)
    Invalid_names_file.close()

这个简单的命令允许打印文件的第一个($ 1)和第三个($ 3)列。软件awk实际上更强大。我想你应该看一下awk的手册页。

一个不错的组合是使用grep和awk和管道。以下代码将仅打印包含“p1”的文件行的第1列和第3列:

awk '{print $1,$3}' <namefile>

如果您想要按行号选择行,则可以用sed替换grep:

grep 'p1' <namefile> | awk '{print $1,$3}'

实际上,awk可以在所有示例中单独使用:

sed 1p <namefile> | awk '{print $1,$3}'

答案 2 :(得分:0)

如果您想保留第一列和第一行中包含特定字符串的列(例如B),那么这应该可行。它假定您的字符串只出现一次。

awk '{if(NR==1){c=0;for(i=1;i<=NF;i++){c++;if($i=="B"){n=c}}}; print $1,$n}' myfile.txt

使用惊人的 awk 可能有更好的解决方案,但这应该可行。

EXPLANATION: 在第一行 (NR==1),它遍历所有列 for(i=1;i<=NF;i++) 直到找到字符串,保存列号,然后打印出来。 如果要将字符串作为变量传递,则可以使用 -v 选项。