С zsh
это должно быть просто вопросом:
precmd() print -z 'foo '
Или, чтобы избежать переопределения команд, поставленных в очередь пользователем, с помощью Alt+q:
zle-line-init() { [ -n "$BUFFER" ] || LBUFFER='foo '; }
zle -N zle-line-init
С помощью bash
вместо xdotool
вы можете использоватьTIOCSTI
ioctl
:
insert() {
perl -le 'require "sys/ioctl.ph";
ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV' -- "$@"
}
PROMPT_COMMAND='insert "foo "'
Это предпочтительнее xdotool
, поскольку он вставляет эти символы непосредственно во входной буфер устройства bash
, с которого считывается. xdotool
будет работать только в том случае, если запущен X-сервер (не будет работать на консоли или реальных терминалах или надssh
(без -X
), например ), который идентифицируется как $DISPLAY
и это тот, с которым вы взаимодействуете, и который работает эмулятор терминала bash
, имеет фокус при оценке $PROMPT_COMMAND
.
Теперь, как и в вашем случае xdotool
, поскольку ioctl()
выполняется до отображения подсказки, а дисциплина линии терминала tty выводится из режима icanon+echo
с помощью readline, вы, вероятно, увидите эхо того foo
из-за дисциплины линии tty, которая портит отображение.
Вы можете обойти это, вместо этого вставив строку, чье эхо невидимо (, например U+200B, если используются исключительно локали Unicode ), и привязать ее к действию, которое вставляет"foo "
:
insert() {
perl -le 'require "sys/ioctl.ph";
ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV' -- "$@"
}
bind $'"\u200b":"foo "'
PROMPT_COMMAND="insert $'\u200b'"
Или вы можете задержать TIOCSTI
ioctl на время, достаточное для инициализации readline:
insert_with_delay() {
perl -le 'require "sys/ioctl.ph";
$delay = shift @ARGV;
unless(fork) {
select undef, undef, undef, $delay;
ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV;
}' -- "$@";
}
PROMPT_COMMAND='insert_with_delay 0.05 "foo "'
Если, как и в подходах zsh
, вы хотите обработать случай, когда пользователь вводит текст до отображения подсказки,вы можете либо
tcflush(0, TCIFLUSH)
в perl
перед TIOCSTI
ioctl (также требуется опция -MPOSIX
)или Как и в подходе zsh
, убедитесь, что foo
вставлен в начале буфера, вставив^A
(при условии, что вы используетеemacs
(режим редактирования по умолчанию ), в котором курсор перемещается в начало строки )до foo
и ^E
после (для перехода к концу):
insert_with_delay 0.05 $'\1foo \5'
или
bind $'"\u200b":"\1foo \5"'
Если
$ cat strings
journal
moon pig
owls
и
$ cat file
I like to journal about owls and moon pigs.
owls are birds. moon pigs are not.
owls owls owls
тогда вы можете использовать GNU awk следующим образом
gawk '
NR == FNR { string[++n] = $0; next}
{
for (i=1; i<=n; i++)
# gsub() return the number of replacements.
# it is a convenient way to count instances of fixed strings.
count[i][FNR] = gsub(string[i], string[i])
if (FNR > max)
max = FNR
}
END {
for (i=1; i<=n; i++) {
for (j=1; j<=max; j++)
printf "%s\t", 0 + count[i][j]
print ""
}
}
' strings file
выходы
1 0 0
1 1 0
1 1 3
Я вообще не объяснял эту awk-программу. Посмотрите, сможете ли вы понять это, и задайте любые вопросы, которые у вас есть.
Основной алгоритм для получения массива счетчиков для каждой строки, который немедленно обрабатывает каждую строку,:
gawk ' NR == FNR { string[++n] = $0; next}
{ for (i=1; i<=n; i++)
printf("%s\t", gsub(string[i],""))
print ""
}
' strings file
Это основано на gsub для подсчета выполненных замен.
Это приведет к выводу:
1 1 0
0 0 2
Это просто транспонированная матрица того, что вы просили. В awk становится немного сложнее транспонировать столбцы и строки. А также обрабатывать более одного файла. Мы можем объединить (конвейер )оба скрипта, используя пустую строку как индикатор изменения файла. Двойная обработка одного и того же файла:
awk '
NR == FNR { string[++n] = $0; next}
FNR==1 && p == 1 { print "" }
{ for (i=1; i<=n; i++) printf("%s\t", gsub(string[i],""))
print ""
p = 1
}
END { print "" }
' strings.txt infile.txt infile.txt |
awk '!/^$/{
for(i=1;i<=NF;i++) f[NR-r][i]=$i ;
if (maxf<NF) maxf = NF ;
if (maxr<(NR-r)) maxr = NR-r ;
}
/^$/{
for( i=1 ; i<=maxf ; i++ )
{
for( j=1 ; j<=maxr ; j++ )
printf("%s\t",f[j][i])
print ( "loop", maxf, maxr, r )
}
r=NR
print ( "" )
maxf=0
maxr=0
delete f
}'
Что дает ответ на вопрос:
1 0
1 0
0 2
1 0
1 0
0 2