Потому что это режим
vi
, а не режимvim
.daw
,diw
предназначены только для vim и не являются самыми полезными. Вы можете сделать то же самое сbdw
,bde
- Stephane Chazelas
При этом вы можете использовать bindkey -s
для привязки одной строки к другой:
bindkey -a -s "diw" "bde"
bindkey -a -s "daw" "bdw"
Теперь при вводе diw
bde
отправляется обратно.
-a
необходим для добавления привязки к режиму vicmd
.
Начиная с версии 5.0.8 zsh также поддерживает текстовые объекты в стиле vim. Так что daw
и diw
должны работать из коробки.
как однострочник
while read -r StartDate && read -r FinalDate <&3; do if [[ ${StartDate} != "INVALID" && ${FinalDate} != "INVALID" ]]; then diff=$(expr $(date -d "${FinalDate}" +"%s") - $(date -d "${StartDate}" +"%s")); printf '%dd:%dh:%dm:%ds\n' $((${diff}/86400)) $((${diff}%86400/3600)) $((${diff}%3600/60)) $((${diff}%60));else echo INVALID; fi; done < startedfile 3<finishedfile
как сценарий
#!/bin/bash
while read -r StartDate && read -r FinalDate <&3; do
if [[ ${StartDate} != "INVALID" && ${FinalDate} != "INVALID" ]]; then
diff=$(expr $(date -d "${FinalDate}" +"%s") - $(date -d "${StartDate}" +"%s"));
printf '%dd:%dh:%dm:%ds\n' $((${diff}/86400)) $((${diff}%86400/3600)) $((${diff}%3600/60)) $((${diff}%60));
else
echo INVALID;
fi;
done < startedfile 3<finishedfile
Это даст такой результат:
0d:0h:2m:13s
0d:1h:0m:55s
INVALID
0d:7h:1m:36s
INVALID
INVALID
Затем вы можете просто вывести это в нужный файл.
РЕДАКТИРОВАТЬ
Как было предложено в комментариях, это можно упростить, установив пакет dateutils
и используя команду datediff
.
while read -r StartDate && read -r FinalDate <&3; do if [[ ${StartDate} != "INVALID" && ${FinalDate} != "INVALID" ]]; then datediff "${StartDate}" "${FinalDate}" -f "%dd:%Hh:%Mm:%Ss";else echo INVALID; fi; done < started.txt 3<finished.txt
В сценарии
#!/bin/bash
while read -r StartDate && read -r FinalDate <&3; do
if [[ ${StartDate} != "INVALID" && ${FinalDate} != "INVALID" ]]; then
datediff "${StartDate}" "${FinalDate}" -f "%dd:%Hh:%Mm:%Ss";
else
echo INVALID;
fi;
done < startedfile 3<finishedfile
Думаю, мне удалось решить вашу проблему с помощью следующего сценария bash:
#!/usr/bin/env bash
sfile=/path/to/start
efile=/path/to/end
ofile=/path/to/out
n=0
while read -r line; do
((n++))
if [[ $line == 'INVALID' ]]; then
echo "INVALID"
continue
fi
start=$(date -u -d "$line" "+%s")
end=$(date -u -d "$(sed -n "${n}p" "$efile")" "+%s")
date -u -d "0 $end sec - $start sec" +"%H:%M:%S"
done<"$sfile" >"$ofile"
Каждая строка начального файла будет прочитана и сравнена с соответствующей строкой в конечном файле. Если строка содержит «INVALID», она выдаст «INVALID» и перейдет к следующей итерации цикла.
Использование ddiff
из GNU dateutils
иbash
:
#!/bin/bash
paste STARTED COMPLETED |
while IFS=$'\t' read start compl; do
if [ "$start" = "INVALID" ] || [ "$compl" = "INVALID" ]; then
echo 'INVALID'
else
ddiff -f '%0H:%0M:%0S' "$start" "$compl"
fi
done
Предполагая, что входные файлы называются STARTED
и COMPLETED
, это создает ввод с разделителями табуляции -для цикла while
с временем начала в первом поле и временем завершения во втором поле. Он читает их и проверяет, соответствует ли какое-либо из двух значений времени INVALID
. Если нет, он вызывает ddiff
вместе с ними.
Вывод этого может быть сохранен в файл с перенаправлением после done
в конце или после имени скрипта в командной строке при вызове скрипта.
Запуск на предоставленных данных:
$ bash script.sh
00:02:13
01:00:55
07:01:36
INVALID
INVALID
Сzsh
:
#! /bin/zsh -
# usage: that-script file1 file2
zmodload zsh/datetime
while
IFS= read -ru3 a &&
IFS= read -ru4 b
do
if
strftime -rs at '%Y-%m-%d %H:%M:%S' "$a" 2> /dev/null &&
strftime -rs bt '%Y-%m-%d %H:%M:%S' "$b" 2> /dev/null
then
d=$((bt - at))
printf '%02d:%02d:%02d\n' $((d/3600)) $(((d/60)%60)) $((d%60))
else
printf '%s\n' $a
fi
done 3< ${1?} 4< ${2?}
Это по-прежнему использует цикл оболочки для обработки текста , что обычно считается плохой практикой но, по крайней мере, здесь мы используем только встроенные команды, что означает, что производительность не будет такой ужасной, как если бы вы вызывали две внешние команды GNU date
для каждой строки ввода.