Как удалить конкретные слова из строк текстового файла?

мой текстовый файл похож на это:

Liquid penetration 95% mass (m) = 0.000205348
Liquid penetration 95% mass (m) = 0.000265725
Liquid penetration 95% mass (m) = 0.000322823
Liquid penetration 95% mass (m) = 0.000376445
Liquid penetration 95% mass (m) = 0.000425341

теперь я хочу удалить Liquid penetration 95% mass (m) от моих строк для получения значений только. Как я должен сделать это?

13
задан 23 October 2017 в 03:10

8 ответов

Если существует только один = знак, Вы могли удалить все прежде и включая = как это:

$ sed -r 's/.* = (.*)/\1/' file
0.000205348
0.000265725
0.000322823
0.000376445
0.000425341

Если Вы хотите изменить исходный файл, используйте -i опция после тестирования:

sed -ri 's/.* = (.*)/\1/' file

Примечания

  • -r используйте ДО, таким образом, мы не должны выходить ( и )
  • s/old/new замена old с new
  • .* любое количество любых символов
  • (things) сохранить things к обратной ссылке позже с \1, \2, и т.д.
22
ответ дан 23 November 2019 в 03:10

Это - задание для awk; принятие значений происходит в последнем поле только (согласно Вашему примеру):

awk '{print $NF}' file.txt
  • NF awk переменная, расширяется до количества полей в записи (строка), следовательно $NF (отметьте $ впереди), содержит значение последнего поля.

Пример:

% cat temp.txt 
Liquid penetration 95% mass (m) = 0.000205348
Liquid penetration 95% mass (m) = 0.000265725
Liquid penetration 95% mass (m) = 0.000322823
Liquid penetration 95% mass (m) = 0.000376445
Liquid penetration 95% mass (m) = 0.000425341

% awk '{print $NF}' temp.txt
0.000205348
0.000265725
0.000322823
0.000376445
0.000425341
21
ответ дан 23 November 2019 в 03:10

С grep и -P для того, чтобы иметь PCRE (Интерпретируют шаблон как Эрл P - Compatible Regular Expression), и -o для печати одного только подобранного шаблона. Эти \K уведомляют, проигнорирует подобранную часть, прибывшую перед собой.

$ grep -oP '.*= \K.*' infile
0.000205348
0.000265725
0.000322823
0.000376445
0.000425341

Или Вы могли использовать cut команда вместо этого.

cut -d= -f2 infile
12
ответ дан 23 November 2019 в 03:10

Так как префикс строки всегда имеет ту же длину (34 символа), можно использовать cut:

cut -c 35- < input.txt > output.txt
11
ответ дан 23 November 2019 в 03:10

Инвертируйте содержание файла с rev, передайте вывод по каналу в cut с пространством как разделитель и 1 как целевое поле, затем инвертируйте его снова для получения исходного числа:

$ rev your_file | cut -d' ' -f1 | rev
0.000205348
0.000265725
0.000322823
0.000376445
0.000425341
6
ответ дан 23 November 2019 в 03:10

Я решил сравнить различные решения, перечисленные здесь. С этой целью я создал большой файл, на основе содержания, обеспеченного OP:

  1. Я создал простой файл, названный input.file:

    $ cat input.file
    Liquid penetration 95% mass (m) = 0.000205348
    Liquid penetration 95% mass (m) = 0.000265725
    Liquid penetration 95% mass (m) = 0.000322823
    Liquid penetration 95% mass (m) = 0.000376445
    Liquid penetration 95% mass (m) = 0.000425341
    
  2. Затем я выполнил этот цикл:

    for i in {1..100}; do cat input.file | tee -a input.file; done
    
  3. Окно терминала было заблокировано. Я выполнился killall tee от другого терминала. Затем я исследовал содержание файла командами: less input.file и cat input.file. Это выглядело хорошим, кроме последней строки. Таким образом, я удалил последнюю строку и создал резервную копию: cp input.file{,.copy} (из-за команд, которые используют оперативную опцию).

  4. Заключительное количество строк в файл input.file 2 192 473. Я получил то число командой wc:

    $ cat input.file | wc -l
    2192473
    

Вот результат сравнения:

  • grep -o '[^[:space:]]\+$'

    $ time grep -o '[^[:space:]]\+$' input.file > output.file
    
    real    0m58.539s
    user    0m58.416s
    sys     0m0.108s
    
  • sed -ri 's/.* = (.*)/\1/'

    $ time sed -ri 's/.* = (.*)/\1/' input.file
    
    real    0m26.936s
    user    0m22.836s
    sys     0m4.092s
    

    Кроме того, если мы перенаправляем вывод в новый файл, команда больше быстрее:

    $ time sed -r 's/.* = (.*)/\1/' input.file > output.file
    
    real    0m19.734s
    user    0m19.672s
    sys     0m0.056s
    
  • gawk '{gsub(".*= ", "");print}'

    $ time gawk '{gsub(".*= ", "");print}' input.file > output.file
    
    real    0m5.644s
    user    0m5.568s
    sys     0m0.072s
    
  • rev | cut -d' ' -f1 | rev

    $ time rev input.file | cut -d' ' -f1 | rev  > output.file
    
    real    0m3.703s
    user    0m2.108s
    sys     0m4.916s
    
  • grep -oP '.*= \K.*'

    $ time grep -oP '.*= \K.*' input.file > output.file
    
    real    0m3.328s
    user    0m3.252s
    sys     0m0.072s
    
  • sed 's/.*= //' (соответственно -i опция делает команду несколько раз медленнее),

    $ time sed 's/.*= //' input.file > output.file
    
    real    0m3.310s
    user    0m3.212s
    sys     0m0.092s
    
  • perl -pe 's/.*= //' ( -i опция не производит большую разницу в производительности здесь),

    $ time perl -i.bak -pe 's/.*= //' input.file
    
    real    0m3.187s
    user    0m3.128s
    sys     0m0.056s
    
    $ time perl -pe 's/.*= //' input.file > output.file
    
    real    0m3.138s
    user    0m3.036s
    sys     0m0.100s
    
  • awk '{print $NF}'

    $ time awk '{print $NF}' input.file  > output.file
    
    real    0m1.251s
    user    0m1.164s
    sys     0m0.084s
    
  • cut -c 35-

    $ time cut -c 35- input.file  > output.file
    
    real    0m0.352s
    user    0m0.284s
    sys     0m0.064s
    
  • cut -d= -f2

    $ time cut -d= -f2 input.file  > output.file
    
    real    0m0.328s
    user    0m0.260s
    sys     0m0.064s
    

Источник идеи.

13
ответ дан 23 November 2019 в 03:10

perl - замените шаблоном /.*= / с пустой строкой //:

perl -pe 's/.*= //' input.file > output.file
perl -i.bak -pe 's/.*= //' input.file
  • От perl --help:

    -e program        one line of program (several -e's allowed, omit programfile)
    -p                assume loop like -n but print line also, like sed
    -i[extension]     edit <> files in place (makes backup if extension supplied)
    

sed - замените шаблоном с пустой строкой:

sed 's/.*= //' input.file > output.file

или (но медленнее, чем вышеупомянутое):

sed -i.bak 's/.*= //' input.file
  • Я упоминаю этот подход, потому что это несколько раз быстрее, чем те, которые в ответе Zanna.

gawk - замените шаблоном ".*= " с пустой строкой "":

gawk '{gsub(".*= ", "");print}' input.file > output.file
  • От man gawk:

    gsub(r, s [, t]) For each substring matching the regular expression r in the string t,
                     substitute the string s, and return the number of substitutions. 
                     If t is not supplied, use $0...
    
4
ответ дан 23 November 2019 в 03:10

Это просто, коротко, и легко записать, понять, и проверить, и мне лично нравится он:

grep -oE '\S+$' file

grep в Ubuntu при вызове с -E или -P, берет стенографию \s означать пробельный символ (на практике обычно пространство или вкладка) и \S означать что-либо, что не является тем. Используя квантор + и привязка конца строки $, шаблон \S+$ соответствия один или несколько непробелов в конце строки. Можно использовать -P вместо -E; значение в этом случае является тем же, но другой механизм регулярных выражений используется, таким образом, у них могут быть различные рабочие характеристики.

Это эквивалентно прокомментированному решению Avinash Raj (только с более легким, более компактным синтаксисом):

grep -o '[^[:space:]]\+$' file

Эти подходы не будут работать, если там мог бы запаздывать пробел после числа. Они могут быть изменены так, они делают, но я не вижу никакой смысл во входе в это здесь. Хотя это иногда поучительно для обобщения решения работать под большим количеством случаев, это не практично для делания так почти так часто, как люди склонны принимать, потому что у каждого обычно нет способа знать, в каком из многих различных несовместимых путей проблема, возможно, в конечном счете должна была бы быть обобщена.


Производительность иногда является важным фактором. Этот вопрос не предусматривает, что вход является очень большим, и вероятно, что каждый метод, который был отправлен здесь, достаточно быстр. Однако в случае, если скорость желаема, вот маленький сравнительный тест на десяти миллионах входных файлов строки:

$ perl -e 'print((<>) x 2000000)' file > bigfile
$ du -sh bigfile
439M    bigfile
$ wc -l bigfile
10000000 bigfile
$ TIMEFORMAT=%R
$ time grep -o '[^[:space:]]\+$' bigfile > bigfile.out
819.565
$ time grep -oE '\S+$' bigfile > bigfile.out
816.910
$ time grep -oP '\S+$' bigfile > bigfile.out
67.465
$ time cut -d= -f2 bigfile > bigfile.out
3.902
$ time grep -o '[^[:space:]]\+$' bigfile > bigfile.out
815.183
$ time grep -oE '\S+$' bigfile > bigfile.out
824.546
$ time grep -oP '\S+$' bigfile > bigfile.out
68.692
$ time cut -d= -f2 bigfile > bigfile.out
4.135

Я выполнил его дважды в случае, если порядок имел значение (как это иногда делает для задач I/O-heavy), и потому что у меня не было машины доступной, который не делал другого материала в фоновом режиме, который мог скосить результаты. От тех результатов я завершаю следующее, по крайней мере временно и для входных файлов размера я использовал:

  • Ничего себе! Передача -P (для использования PCRE), а не -G (значение по умолчанию, когда никакой диалект не указан), или -E сделанный grep быстрее по порядку величины. Таким образом для больших файлов, может быть лучше использовать эту команду, чем один показанный выше:

    grep -oP '\S+$' file
  • WOW!! cut метод в ответе αғsнιη, cut -d= -f2 file, по порядку величины, более быстрому, чем даже более быстрая версия моего пути! Это был победитель в сравнительном тесте pa4080 также, который покрыл больше методов, чем это, но с меньшим входом - и который является, почему я выбрал его, всех других методов, для включения в мой тест. Если производительность важна, или файлы огромны, я думаю αғsнιη cut метод должен использоваться.

    Это также служит напоминанием что простое cut и paste об утилитах нельзя забыть и нужно, возможно, предпочесть, когда применимо, даже при том, что существуют более сложные инструменты как grep это часто предлагается как решения первой строки (и что я являюсь лично более приученным к использованию).

5
ответ дан 23 November 2019 в 03:10

Другие вопросы по тегам:

Похожие вопросы: