删除文本文件中不包含字符串的所有行

时间:2012-02-15 09:26:20

标签: shell sed

所以我有一个txt文件,其中每一行都是文件路径,我想:

  1. 阅读此txt文件(逐行)。
  2. 删除所有不以,-,.txt
  3. 结尾的行
  4. 在其余行中,删除从上一个/,-,.txt之后的所有内容。
  5. 将输出写入新的txt。
  6. 如何用sed完成?

    输入:

    /a/b1/
    /a/b1/car
    /a/b1/car/bil/
    /a/b1/car/bil/,-,.txt
    /a/b2/
    /a/b2/flower
    /a/b2/flower/bil/
    /a/b2/flower/bil/,-,.txt
    /a/b2/
    /a/b2/boat
    /a/b2/boat/baat/
    /a/b2/boat/baat/abc,-,.txt
    

    第二步:

    /a/b1/car/bil/,-,.txt
    /a/b2/flower/bil/,-,.txt
    /a/b2/boat/baat/abc,-,.txt
    

    第三步/期望输出:

    /a/b1/car/bil/
    /a/b2/flower/bil/
    /a/b2/boat/baat/
    

7 个答案:

答案 0 :(得分:3)

sed -n '/,-,\.txt$/s|/[^/]*$||p' input.txt > output.txt

它的作用:

它从input.txt开始一次读取一行; -n告诉它默认不打印行。对于与模式,-,\.txt$匹配的每一行,将删除由/字符后跟零个或多个非/个字符组成的所有字符,直至该行的末尾(即,从最后 /到最后一行);我使用|作为分隔符,因此我不必转义/

这是对您的要求的相当直接的再现。

现在您已发布示例输入和输出,我发现您要保留最终/(这与您的要求不一致)“删除从上一个/到{{的所有内容1}}“)。要做到这一点:

,-,.txt

根据您的样本输入,这会产生您的预期结果。

如果我在飞行中这样做,我可能会使用更简单的方法,将sed -n '/,-,\.txt$/s|/[^/]*$|/|p' input.txt > output.txt sed结合起来:

grep

答案 1 :(得分:1)

是否需要sed?我会使用python这样的东西,sed很快就会过于复杂。

#!/usr/bin/env python
import sys

def main(fin, fout):
    with open(fin) as f:
        lines = []
        for line in f.readlines():
            if line.endswith(',-,.txt\n'):
                lines.append('/'.join(line.split('/')[:-1]) + '/\n')

    with open(fout, 'w') as f:
        for line in lines:
            f.write(line)

def usage():
    print sys.argv[0], "filename new_file"
    print 'remove all lines not ending with ",-,.txt"'
    print 'print the resulting lines, up to their last "/" to new file'


if __name__ == '__main__':
    if len(sys.argv) == 3:
        main(sys.argv[1], sys.argv[2])
    else:
        usage()

用样品测试

/a/b1/car/bil/
/a/b2/flower/bil/
/a/b2/boat/baat/

答案 2 :(得分:1)

echo -e "foo,-,.txt\nbar,-,.png" | sed -rn '/,-,\.txt/{s/^(.*),-,\.txt$/\1/p}'

解释:

sed -rn : 
    -r  : use regular expressions, which allows (.*) as  
          capturing group without masking the parens. 
    -n  : no output by default 
    '/pattern/{ list of commands}' 
    {s/pattern/replacement/p} substitute pattern with replacement,  
       then print. 
    /^(.*)foo$/ : from line begin ^ to line end $, with anything 
       before foo being captured, to be outputted with \1

答案 3 :(得分:1)

$ grep -oP '.*/(?=[^/]*,-,\.txt$)' input.txt
/a/b1/car/bil/
/a/b2/flower/bil/
/a/b2/boat/baat/

答案 4 :(得分:0)

这应该做的工作:

sed -r '/,-,\.txt$/!d' <file> | awk -F, '{print $1}'

注意:

  • sed命令会删除与模式不匹配的行(!d
  • awk命令只打印一行中的第一个字段,其中多个字段以逗号分隔。根据问题中提供的输入和所需输出,这似乎是您正在寻找的。

答案 5 :(得分:0)

在你的问题中,你向我们展示了两个步骤,如果它是由sed在线人员在一个短片中完成的话可以接受吗?

sed -r  '/,-,\.txt/!d; s#/[^/]*$#/#' yourFile

适用于您的示例数据。

见下面的测试:

kent$  cat t.txt
/a/b1/
/a/b1/car
/a/b1/car/bil/
/a/b1/car/bil/,-,.txt
/a/b2/
/a/b2/flower
/a/b2/flower/bil/
/a/b2/flower/bil/,-,.txt
/a/b2/
/a/b2/boat
/a/b2/boat/baat/
/a/b2/boat/baat/abc,-,.txt

kent$  sed -r  '/,-,\.txt/!d; s#/[^/]*$#/#' t.txt
/a/b1/car/bil/
/a/b2/flower/bil/
/a/b2/boat/baat/

答案 6 :(得分:0)

这可能对您有用:

sed 's/[^/]*,-,\.txt$//p;d' file