Отфильтровать текст из каждого файла и превратить его в список значений, разделенных запятыми

exit 1 сигнализирует об ошибке. Для такого сценария вы не должны включать туда exit .

Попробуйте вместо этого эту функцию. Вы можете указать хост и порт в командной строке для startManagedWeblogic.shm или экспортировать переменные перед запуском сервера. Если вы читаете сценарий startManagedWebLogic.sh, вы должны найти переменную, которую можно экспортировать, прежде чем запускать сценарий для перенаправления вывода вместо того метода, который я использовал. Вы можете сделать то же самое в своем скрипте Python.

Сценарии запуска WebLogic выполняются до остановки сервера. Вам нужно будет записывать фоновый вывод в файл и отключать сервер. (Рассмотрите возможность использования nodeManager для запуска сервера.) Затем следите за файлом, пока он не запустится.

function start_server {
    ~/bin/startManagedWeblogic.sh HOSTNAME PORT &> weblogic.out &
    disown
    ~/bin/tailUntilRunning.py weblogic.out
    echo 'Shell script finished'

}

Есть функции WLST, которые вы можете использовать для запуска сервера, хотя вам нужно будет использовать wlst.sh в качестве интерпретатора для вашего скрипта python (Jython 2.1).

3
03.05.2016, 15:32
2 ответа

С помощью gnu sed:

sed -Es '/pattern1|pattern2|pattern3/{
s/.*:[[:blank:]]*//;H}
$!d;x;/^\n$/d;s/\n(.*)/\1,/;s/\n/,/g' folder/*.txt > list.txt

где list.txt содержимое будет примерно таким:

file1match1,file1match2,
file2match1,
file4match1,file4match2,file4match3,

так file3 отсутствует в выводе, поскольку не было строки, соответствующей pattern*.
Как это работает: обрабатывает каждый файл -sотдельно, удаляя (через s/.*:[[:blank:]]*//) ненужную часть в строках, соответствующих pattern* и добавляя результат в Hold буфер. Он удаляет каждую строку, кроме la$t, когда он exменяет буферы. Если в пространстве шаблона есть только \newline, это означает, что ни одна строка в этом файле не соответствует pattern*, поэтому он удаляет пространство шаблона. Иначе он удаляет ведущую \nстроку, заменяет оставшиеся запятыми и добавляет последующую запятую.

С другими sedами вам придется выполнить цикл:

for file in folder/*.txt do
sed '/pattern1\|pattern2\|pattern3/{
s/.*:[[:blank:]]*//
H
}
$!d
x
/^\n$/d
s/\n\(.*\)/\1,/
s/\n/,/g' "$file"
done > list.txt
2
27.01.2020, 21:13

OK, прежде всего, не используйте цикл for! Это очень неэффективно. Просто задайте grep все имена файлов сразу:

grep 'sometext:' folder/*.txt

В этом случае, однако, я бы использовал awk вместо grep. Я сделал 10 копий вашего входного файла для проверки:

$ awk '{
        if($1~/sometext|someothertext|somedifferenttext/){
            printf "%s,",$2
        }
        if(FNR==1 && NR>1){
            print ""
        }
    }
    END{ print "" }' folder/*txt 
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,

Пояснение

awk - это язык сценариев, который читает входные данные построчно и разбивает каждую строку на пробельные символы (по умолчанию, вы можете изменить это с помощью -F) на поля. Первое поле будет $1, второе $2 и т.д.

  • if($1~/sometext|someothertext|somedifferenttext/){ : если первое поле соответствует sometext или someothertext или somedifferenttext. Обратите внимание, что это также будет соответствовать foosometext. Если вы хотите ограничиться точными совпадениями, измените это на:

    if($1=="sometext:" || $1=="someothertext:" || $1=="somedifferenttext:"){
    
  • printf "%s,",$2 : если условие выше выполнено, выведите 2-е поле, за которым следует запятая.

  • if(FNR==1 && NR>1){ print "" } : NR - номер текущей строки ввода, а FNR - номер строки текущего файла. Таким образом, печать новой строки (вызов awk print добавляет новую строку по умолчанию, поэтому печать ничего не означает печать новой строки) каждый раз, когда номер строки файла равен 1, но не в том случае, если общее количество обработанных строк также равно единице. Другими словами, печатайте новую строку каждый раз, когда мы начинаем читать новый файл.

  • END{ print "" }' : также выведите новую строку после обработки всех файлов.

Обратите внимание, что это предполагает, что у вас есть только 2 поля в строке. Если вам нужно вывести всю строку, вы можете использовать (для примера используется версия, которая печатает только точные совпадения):

awk '{
    if($1=="sometext:" || 
       $1=="someothertext:" || 
       $1=="somedifferenttext:"){
        $1=""; 
        printf "%s,",$0
    }
    if(FNR==1 && NR>1){print ""}
    }END{print ""}' folder/*txt | sed 's/^ //'

Разница в том, что мы используем $0 (полная строка) вместо $2 и устанавливаем $1 в пустую строку перед печатью. В результате в начале печатается лишний пробел (поскольку пустой $1 все еще считается полем), поэтому мы пропускаем его через sed, чтобы удалить.


В качестве альтернативы, вы можете сделать все это в Perl:

 $ perl -lane '
    if($F[0]=~/(sometext|someothertext|somedifferenttext):/){
        push @k,@F[1..$#F]
    } 
    if(eof){
        print join ",", @k; @k=();
    }' folder/file*
Hello,World,!
Hello,World,!
Hello,World,!
Hello,World,!
Hello,World,!
Hello,World,!
Hello,World,!
Hello,World,!
Hello,World,!
Hello,World,!
Hello,World,!

Или, чтобы также иметь трейлинг ,:

 $ perl -lane '
    if($F[0]=~/^(sometext|someothertext|somedifferenttext):$/){
        push @k,@F[1..$#F]
    } 
    if(eof){
        print join ",", @k , ""; @k=();
    }' folder/file*
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,

Объяснение

Основная идея здесь та же. Переключатель -a в Perl заставляет его вести себя как awk, разбивая каждую строку ввода на массив @F. Затем, если 1-й элемент массива является одной из нужных строк, остальные поля (@F[1..$#F]) добавляются в массив @k. Если мы достигаем конца файла (if(eof)), мы соединяем содержимое массива @k запятыми и печатаем полученную строку.


Наконец, вот один из способов сделать это так, как вы пытались (при использовании GNU grep):

$ for f in folder/*; do 
    grep -hoP '^(sometext|someothertext|somedifferenttext): \K.*' "$f" | 
        perl -pe 's/\n/,/; END{print "\n"}'; 
  done
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
Hello,World,!,
4
27.01.2020, 21:13

Теги

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