Перенаправление с использованием tee и sed

Проблема

Значение будет вызывать тип Value<Object>, потому что вы неправильно интерпретировали лямбда. Подумайте об этом, как вы называете лямбдой непосредственно методом применения. Итак, что вы делаете:

Boolean apply(Value value);

, и это правильно выводится на:

Boolean apply(Value<Object> value);

, поскольку вы не указали тип значения.

Простое решение

Правильно вызовите лямбда:

Foo.foo((Value<Boolean> value) -> true).booleanValue();

это будет выведено на:

Boolean apply(Value<Boolean> value);

(My) Рекомендуемое решение

Ваше решение должно быть немного более ясным. Если вам нужен обратный вызов, вам потребуется значение типа, которое будет возвращено.

Я создал общий интерфейс обратного вызова, общий класс Value и UseClass, чтобы показать, как его использовать.

Интерфейс обратного вызова

/**
 *
 * @param <P> The parameter to call
 * @param <R> The return value you get
 */
@FunctionalInterface
public interface Callback<P, R> {

  public R call(P param);
}

Класс значения

public class Value<T> {

  private final T field;

  public Value(T field) {
    this.field = field;
  }

  public T getField() {
    return field;
  }
}

Использование класса Class

public class UsingClass<T> {

  public T foo(Callback<Value<T>, T> callback, Value<T> value) {
    return callback.call(value);
  }
}

TestApp с основным

public class TestApp {

  public static void main(String[] args) {
    Value<Boolean> boolVal = new Value<>(false);
    Value<String> stringVal = new Value<>("false");

    Callback<Value<Boolean>, Boolean> boolCb = (v) -> v.getField();
    Callback<Value<String>, String> stringCb = (v) -> v.getField();

    UsingClass<Boolean> usingClass = new UsingClass<>();
    boolean val = usingClass.foo(boolCb, boolVal);
    System.out.println("Boolean value: " + val);

    UsingClass<String> usingClass1 = new UsingClass<>();
    String val1 = usingClass1.foo(stringCb, stringVal);
    System.out.println("String value: " + val1);

    // this will give you a clear and understandable compiler error
    //boolean val = usingClass.foo(boolCb, stringVal);
  }
}
-2
задан Jean 13 July 2018 в 21:39
поделиться

3 ответа

Если вы используете Bash, то есть соответствие Posix скрипту не важно, вы можете использовать подстановку процесса :

perl test.pl | tee >(sed 's/\x1b\[[0-9;]*m//g' > test.log)
0
ответ дан Daniel Schepler 17 August 2018 в 12:09
поделиться
  • 1
    Я использую tcsh, и он говорит Missing name for redirect., когда я выполняю команду – Jean 13 July 2018 в 21:58

После выяснения:

Решение Daniel Schelper является правильным для обычных человеческих оболочек (google Почему бы не использовать csh). К сожалению, иногда у нас нет выбора, поэтому одно решение:

perl test.pl | tee /dev/stderr | sed 's/\x1b\[[0-9;]*m//g' > test.log

Что это делает, это дублировать stdout на stderr, а только каналы stdout - вперед. Выход из perl будет отображаться на экране (через stderr). У этого есть очевидное предостережение, что любые реальные ошибки могут быть скрыты. Более безопасным решением может быть:

perl test.pl > /tmp/temp.log; cat /tmp/tmp.log & sed 's/\x1b\[[0-9;]*m//g' /tmp/tmp.log

, который, конечно же, делает дополнительный файл. Хорошие параметры в csh обычно включают в себя более промежуточные файлы по сравнению с оболочками Bourne.


Старый ответ

tee всегда должен быть последней программой с каналами (если вы не хотите регистрировать что-то наполовину, я думаю), и есть имя файла в качестве аргумента. Первое состоит в том, что все дело в том, чтобы видеть вывод на экране (не передавать его), а второй - потому, что tee обычно не полезен, когда он не отправляет вывод в файл.

Как и в настоящий момент, вы передаете stdout через tee в следующий канал, sed, и все это сбрасывает на test.log с помощью оператора >. Фактически, вы не должны иметь > и tee:

perl test.pl | sed 's/\x1b\[[0-9;]*m//g' | tee test.log

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

perl test.pl | tee mid.log | sed 's/\x1b\[[0-9;]*m//g' > test.log
2
ответ дан kabanus 17 August 2018 в 12:09
поделиться
  • 1
    Моя цель - отправить все, напечатанные с test.pl до STDOUT, и сбросить отфильтрованную версию с той же до test.log. Как мне это сделать? – Jean 13 July 2018 в 20:58
  • 2
    @DanielSchepler Только что вернулся - хотите ли вы написать это как свой собственный ответ? – kabanus 13 July 2018 в 21:03

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

perl test.pl | tee -i /dev/stderr | sed -f sed.sed > test.log

Программа perl переключит свой вывод на стандартный вывод. Тройка выйдет на сцену и примет ее как stdin и выкачайте ее в stderr и stdout. Программа sed будет принимать stdout и принять ее как stdin и выкачать ее из stdout, которая перенаправляет ее на test.log. Stderr будет направлен на терминал.

N.B. Это может привести к нежелательным побочным эффектам.

1
ответ дан potong 17 August 2018 в 12:09
поделиться
  • 1
    Я прихожу через 13 часов и отправляю в то же время, что и вы, это безумие. – kabanus 14 July 2018 в 10:40
  • 2
    Оно работает. Но я получаю ошибку Broken pipe, когда я убиваю программу. – Jean 15 July 2018 в 13:43
Другие вопросы по тегам:

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