Переопределить `cd` или другие встроенные функции более одного раза

Это можно сделать с помощью цикла while:

while read l; do
  [ ${#l} -gt 65 ] && \
    echo "$l" | langid --line | grep -q "is" && \
    echo "$l"
done <file

  • читать l читать ввод построчно и сохранять текущую строку в переменной $ 1 .
  • [$ {# l} -gt 65] , если строка содержит более 65 символов.
    • echo "$ l" | langid --line | grep -q "is" обработать строку и grep для языка, обратите внимание на -q , grep будет молчать. Мы просто хотим проверить, есть ли строка, вывода нет.
    • echo "$ l" Если строка есть, вывести исходную строку.
  • <файл использовать содержимое файла в качестве входных данных.

Редактировать : Вышеупомянутая команда запускает команду langid в каждой строке, это очень медленно. Если вы хотите, чтобы он работал за один проход (быстрее), используйте следующее:

awk 'FNR==NR{a[NR]=$0}
  FNR!=NR&&$1~"is"{print a[FNR]}' \
<(sed -n '/^.\{65\}/p' file) \
<(sed -n '/^.\{65\}/p' file | langid --line)
  • awk обрабатывает два «файла»:
    • Вывод sed -n Файл '/^.\{65\}/p' : все предложения, содержащие 65 или более символов.
    • Вывод sed -n '/^.\{65\}/p' file | langid --line , который обрабатывает все строки из 65 или более символов за один проход.
  • Внутри awk :
    • FNR == NR применяется в первом «файле»
    • a [NR] = $ 0 Заполните массив номером строки как индекс
    • FNR! = NR && $ 1 ~ "is" применяется ко второму "файлу" и проверяет, содержит ли строка строку is
    • print a [ FNR] , если это правда, выведите соответствующую строку в ранее созданном массиве a , который содержит исходное предложение.
0
02.05.2018, 07:59
2 ответа

Вы можете скопировать тело определения cdв новую функцию с именем prev_cd. Используйте declare -f cd, чтобы получить это определение, а затем eval, чтобы переопределить его.

definition_prev_cd="prev_$(declare -f cd)"
eval "${definition_prev_cd}"
unset definition_prev_cd  # clean up, no reason to leave this string around

cd () {
   prev_cd "$@"
   echo "do my own thing"
}

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

2
28.01.2020, 02:32

Нет, несколько cdимен не могут быть выполнены.

Да, может быть несколько "вещей", называемых cd, например:

$ cd(){ echo function cd; }
$ alias cd='cd -eP'

И еще, встроенный cd определен. В таких условиях это происходит:

$ type -a cd
cd is aliased to `cd -eP'
cd is a function
cd ()
{
    echo function cd
}
cd is a shell builtin

Как видите, несколько "вещей" называются cd, да, но только одна из них будет выполнена. Приведенный выше список находится в порядке поиска, то есть первое найденное определение cdвыполняется. Ну, не совсем так, псевдоним заменит слово cdопределением псевдонима cd -eP, а это, в свою очередь, вызовет -вызов cd, который (в порядке списка )вызовет функция кд.

Так что нет, не совсем, нельзя иметь несколько cdи ожидать, что все они будут выполнены.

0
28.01.2020, 02:32

Теги

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