Удалить все строки в текстовом файле, которые не содержат строки - PullRequest
2 голосов
/ 15 февраля 2012

Итак, у меня есть текстовый файл, где каждая строка представляет собой путь к файлу, я хотел бы:

  1. Прочитать этот текстовый файл (построчно).
  2. Удалите все строки, которые не заканчиваются ,-,.txt
  3. В оставшихся строках удалите все, начиная с последней / до ,-,.txt.
  4. Записать вывод в новыйтекст.

Как это можно сделать с помощью 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 ]

3 голосов
/ 15 февраля 2012
sed -n '/,-,\.txt$/s|/[^/]*$||p' input.txt > output.txt

Что он делает:

Он читает строку за раз от input.txt;-n говорит, что по умолчанию не печатать строки.Для каждой строки, которая соответствует шаблону ,-,\.txt$, все, состоящее из символа /, за которым следует ноль или более не / символов, до конца строки, удаляется (т. Е. Из последнего / до конца строки);Я использую | в качестве разделителя, поэтому мне не нужно избегать /.

Это довольно прямолинейное исполнение ваших требований.

Теперь, когда вы разместили образецВвод и вывод, я вижу, что вы хотите сохранить окончательный / (что не соответствует вашему требованию "удалить все с последнего / до ,-,.txt").Чтобы сделать это:

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

Это дает ожидаемые результаты с учетом вашего образца ввода.

Если бы я делал это на лету, я мог бы использовать более простой подход, комбинируя sed иgrep:

grep ',-,\.txt$' input.txt | sed 's|/[^/]*$|/|' > output.txt
1 голос
/ 15 февраля 2012
$ grep -oP '.*/(?=[^/]*,-,\.txt$)' input.txt
/a/b1/car/bil/
/a/b2/flower/bil/
/a/b2/boat/baat/
1 голос
/ 15 февраля 2012
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
1 голос
/ 15 февраля 2012

Нужно ли быть 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/
0 голосов
/ 15 февраля 2012

Это может работать для вас:

sed 's/[^/]*,-,\.txt$//p;d' file
0 голосов
/ 15 февраля 2012

в своем вопросе вы показали нам два шага, допустимо ли, если это делается в одном коротком случае с помощью sed onliner?

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/
0 голосов
/ 15 февраля 2012

Это должно сделать работу:

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

Примечания:

  • Команда sed удаляет строки, которые не соответствуют шаблону (!d)
  • Команда awk печатает только первое поле в строке с несколькими полями, разделенными запятыми. Похоже, это то, что вы ищете в соответствии с входными данными и желаемыми результатами, указанными в вопросе.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...