Я изучаю bash
скриптинг в данный момент, и это казалось превосходной простой задачей для практики с, поэтому я написал следующее. (Мой другой ответ дает простой хак расширения истории, но это полный сценарий, и я счел его достойным сделать дополнительный ответ.) Я считаю, что это POSIX совместимо и должно работать с # !/bin/sh
, но не 100% уверен. EDIT: Фактически = ~
несовместим с POSIX. Вы можете взять эту выписку и позволить вырезать
вернуть ошибку, хотя.
#!/bin/bash
fieldtocut=1
delimiter=','
usage () {
cat << EOF
usage: $0 [-f FIELD] [-d DELIMITER] file1..
Cuts field FIELD from each file and pastes it.
Default field is 1, default delimiter is ','
EOF
exit $1
}
while getopts ':f:d:' opt ; do
case $opt in
f)
if [[ $OPTARG =~ ^[0-9]+$ ]] ; then
fieldtocut="$OPTARG"
else
usage 1
fi
;;
d)
delimiter=$OPTARG
;;
*)
usage 1
;;
esac
done
shift $((OPTIND-1))
[ $# -eq 0 ] && usage 0
pasteargs=''
for file in "$@" ; do
pasteargs=$(printf '%s' "$pasteargs" '<(cut -d$delimiter -f$fieldtocut ' "$file" ') ')
done
eval paste $pasteargs
-121--53856-
Вы можете автоматизировать это с помощью глоббинга, в частности, квалификатора e
glob , плюс eval
, но это не очень красиво, и цитирование является сложным:
eval paste *.csv(e\''REPLY="<(cut -d, -f1 $REPLY)"'\')
\' ...\'
является некоторым кодом для выполнения для каждого совпадения с глобусом. Он выполняется с переменной REPLY
, набора к совпадению, и может изменить его. REPLY = « создает последовательность , если соответствует file1.csv
. Двойные кавычки необходимы для того, чтобы часть после знака равенства не разворачивалась при выполнении кода e
отдельно от подстановки значения REPLY
.
Было бы лучше скрыть сложность функции. Минимально протестирован.
function map {
emulate -LR zsh
local cmd pre
cmd=()
while [[ $# -ne 0 && $1 != "--" ]]; do
cmd+=($1)
shift
done
if ((!$#)); then
echo >&2 "Usage: $0: COMMAND [ARGS...] -- PREPROCESSOR [ARGS...] -- FILES..."
return 125
fi
shift
while [[ $# -ne 0 && $1 != "--" ]]; do
pre+="${(q)1} "
shift
done
if ((!$#)); then
echo >&2 "Usage: $0: COMMAND [ARGS...] -- PREPROCESSOR [ARGS...] -- FILES..."
return 125
fi
shift
eval "${(@q)cmd}" "<($pre${(@q)^@})"
}
Пример использования (синтаксис напоминает zargs
):
map paste -- cut -d, -f1 -- *.csv
-121--53853-
Bash не записывает свою историю в файл истории, пока не завершит его или вы явно не вызовете history -w
. Так что если вы только что добавили свой пароль в историю текущей оболочки, он еще не был записан в .bash _ history
, он просто сидит там в памяти. Для просмотра списка последних команд можно запустить fc -l
, затем history -d
для удаления записи.
$ echo swordfish swordfish Oops, that was my password! $ fc -l -2 1234 ls 1235 echo swordfish $ history -d 1235 $ fc -l -3 1234 ls 1235 fc -l -2 1236 history -d 1236
Если файл истории уже написан (например, из-за наличия history -w
в PROMPT _ COMMAND
или ловушки отладки), выполните это действие и отредактируйте .bash _ history
.
Если вы хотите забыть историю текущей оболочки, отмените установку HISTFILE
и убедитесь, что она не установлена до выхода из оболочки. Если вы хотите забыть текущую историю до этого момента, но начать запись, вы можете вызвать history -c
. Если вы хотите забыть все записи истории 3, кроме последних, установите значение HISTFILE = 3
, затем (в отдельной командной строке) вернитесь к обычному значению.
Вы можете поместить вычисление в круглые скобки...
root@beaglebone:~/bbbrtc# date -d "@1524884843+(1 month)"
Sat Apr 28 03:07:23 UTC 2018
С помощью ast -open date
(, возможно, встроенная дата ksh93, в зависимости от того, как он был построен, и среды):
$ date -d '#1234567890'
Fri Feb 13 23:31:30 GMT 2009
$ date -d "#1234567890 30 days"
Sun Mar 15 23:31:30 GMT 2009
(ast date
не поддерживает смещения, выраженные в месяцах (месяцы не имеют фиксированной длины )).
В GNU date
вы можете использовать старый метод (до того, как @epoch
была добавлена поддержка ), где вы выражаете время эпохи как смещение в секундах относительно 1970 года -01 -01 00 :00 :00 UTC:
$ date -d '1970-01-01T00:00:00Z + 1234567890 seconds'
Fri 13 Feb 23:31:30 GMT 2009
$ date -d '1970-01-01T00:00:00Z + 1234567890 seconds + 1 month'
Mon 16 Mar 23:31:30 GMT 2009
Обратите внимание, однако, что здесь 1 месяц равен 31 дню , предположительно потому, что date
считает, что смещение 1 месяц относится к январю 1970 года.
Если ваш date
относится к GNU, и вы хотели бы, чтобы он продемонстрировал поведение для месяцев -относительных дат, при котором смещение в один -месяц дает вам тот же день месяца (при условии, что существует такое день в следующем месяце )совпадает с начальной датой (, хотя и не обязательно в тот же час дня, если в интервале )произошло какое-то изменение летнего времени, тогда вы, вероятно, захотите использовать @ двухэтапный подход Исаака .