Получение подстрок между разделителями несколько раз из одной строки без зацикливания

На старом дистрибутиве без du --inodes,

find . -type d -ls | sort -n -k7,7

перечислит все каталоги в порядке увеличения размера, так что вы получите каталоги с наибольшим количеством файлов (или содержащие наибольшее количество файлов в какой-то момент) в конце списка. Выполнение команды find может занять некоторое время, но с этим мало что можно поделать - даже при подходе "разделяй и властвуй" du придется считывать с диска такой же объем информации.

2
28.06.2016, 17:55
5 ответов

Если вас устраивает такая структура, как:

string1
string2
string3

, я бы просто заменил вам разделители на новую строку. Что-то вроде этого должно вас приблизить:

sed "s/\(aaa\)\|\(bbb\)/\n/g" test.txt

Edit

Как указано ниже @clk, мой первый ответ может давать двойные символы новой строки. Переход на что-то вроде:

sed "s/\(\s\)\?aaa\(\s\)\?/bbb/g" test.txt | sed "s/b*//g"

для меня дает:

 string1 string2 string3

, который также работает точно так же, когда вводится, например:

echo 'aaa string1 bbb aaa string2 bbb aaa string3 bbb' | sed "s/\(\s\)\?aaa\(\s\)\?/bbb/g" | sed "s/b*//g"

Не очень красивый ответ, но быстрый и грязный и дает вам формат, который вы просите.

0
27.01.2020, 22:11

Использование только sed (с флагом -r для расширенного регулярного выражения)

echo "aaa string1 bbb aaa string2 bbb aaa string3 bbb" | sed -r 's/(aaa|bbb) ?//g'

Возвращает

string1 string2 string3 

У вас также есть эта версия с использованием tr и grep (с -vE ):

echo "aaa string1 bbb aaa string2 bbb aaa string3 bbb" | tr ' ' '\n'| grep -vE '(aaa|bbb|^$)'

Возвращает

string1
string2
string3

tr просто заменяет пробел на новую строку. grep -vE использует регулярное выражение («E») и исключает совпадающие строки («v»).

Третья версия использует sed (без флага) и grep (так же, как и в предыдущей версии):

echo "aaa string1 bbb aaa string2 bbb aaa string3 bbb" | sed 's/\s/\n/g' | grep -vE '(aaa|bbb|^$)'

Делает почти то же самое, что и вторая версия, используя sed вместо tr.

Редактировать: Также добавлен ^ $ в строку поиска grep, чтобы убедиться, что она не возвращает нежелательные символы новой строки.

Edit2: Я вижу, вы изменили OP. Выше ответ на исходный вопрос. Ниже я написал сценарий, который может вам помочь: http: // pastebin.com / uKWAGE0Y

-1
27.01.2020, 22:11

Чтобы разобрать XML, используйте парсер XML.

XMLStarlet - это парсер XML командной строки, который очень хорошо подходит для такого рода ситуаций.

Предполагая, что ваш XML является полным (в нем отсутствует в конце, как он написан сейчас), вы можете извлечь значение узла Output_Path с помощью

$ xml --template --value-of '//Output_Path' -nl input.xml
xxxxxxxx.xx.xxxxxxx:/data/xxxxxxxx/xxxxxxxxxxx/summer2016/relax/r053_x.xxMx.xxR_400k_neos2/r053_x.xxMx.xxR_400k_neos2.pbs.o4382
xxxxxxxx.xx.xxxxxxx:/data/xxxxxxxx/xxxxxxxxxxx/summer2016/relax/r061_x.xxMx.xxR_20k_neos2/0R_20k_neos2.pbs.o4396

Параметр --template указывает, что мы ищем значение именованного узла в любом месте входного документа. -nl в конце заставляет XMLStarlet выводить новую строку после последних данных.

Вы также можете передать в XMLStarlet:

$ yourcommand | xml sel ...
0
27.01.2020, 22:11

Попробуйте следующее:

xmlstarlet sel -t -v //Output_Path -nl data.xml
2
27.01.2020, 22:11

Если grep вашей системы поддерживает PCRE, вы можете сделать

$ echo 'aaa string1 bbb aaa string2 bbb aaa string3 bbb' | 
  grep -oP '(?<=(aaa|bbb) )\w*?(?= (aaa|bbb))'
string1
string2
string3

или если вам нужно обработать более общее количество окружающих пробелов

$ echo 'aaa string1 bbb aaa string2 bbb aaa string3 bbb' |
  grep -oP '(aaa|bbb)\s+\K\w*?(?=\s+(aaa|bbb))'
string1
string2
string3
1
27.01.2020, 22:11

Теги

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