EDID на моем мониторе был поврежден. Мой Macbook pro вообще перестал отображаться на мониторе через несколько месяцев после написания вышеуказанного поста, что побудило меня протестировать и мой рабочий стол, и ноутбук на телевизоре Vizio. Оба работали безупречно. Я не упомянул выше, что у меня также были Windows 10 и Linux на одной машине. Windows могла отображать правильно все время, что заставило меня думать, что это что-то помимо монитора. Оказывается, MacOS, Linux и Windows по-разному реагируют на повреждение EEPROM, содержащего информацию EDID. Windows, казалось, продолжала работать нормально, Mac в конечном итоге вообще перестал работать, а Linux будет отображаться, но с неправильным разрешением.
Я купил новый монитор, и все работает нормально.
С помощью GNU awk
вы можете сделать:
gawk -i inplace -F, -v OFS=, -v date_field=4 '
(t = mktime(gensub("-", " ", "g", $date_field) " 0 0 0")) > 0 {
$NF = strftime("%A", t)};1' your-file
-i inplace
:включает в -режим редактирования места gawk, при котором вывод записывается в новый файл, предназначенный для замены входного файла. -F,
и -v OFS=,
устанавливают разделители полей ввода и вывода mktime()
— это расширение GNU awk, которое анализирует строку в формате year month day hour minute second
и возвращает соответствующее время эпохи Unix. Здесь,мы используемgensub()
(другое расширение gawk ), чтобы заменить -
пробелами в 4-м поле (YYYY-MM-DD
), чтобы передать YYYY MM DD 0 0 0
время в mktime()
. (t = mktime(...)) > 0 {...}
и 1
— это две пары condition {action}
, которые запускаются для каждой входной записи (здесь строки).
mktime()
(, присвоенное t
), чем 0(mktime()
возвращает -1
, если не удается проанализировать спецификацию даты ), и в этом случае запускается действие .strftime()
(другое расширение gawk ), подобное его эквиваленту C, используется для форматирования времени (здесь время эпохи unix, хранящееся в t
с форматом%A
:локализованное название дня недели ). Результат присваиваем NF
-му полю ($NF
), NF
— специальной переменной, которая содержит количество полей в текущей записи, а $
— оператору для получения содержимого полей (или полной записи с$ 0
). во втором(1
)отсутствует часть действие , которая по умолчанию{print}
(печатает текущую запись ), а условие (1
)всегда верно. Это идиоматический короткий способ безоговорочно распечатать текущую запись, если вы хотите быть более подробным, вы можете сделать:
gawk -i inplace \
-v FS=, \
-v OFS=, \
-v date_field=4 \
-v current_record=0 \
-v always=1 '
{
date_for_mktime = gensub("-", " ", "g", $date_field) " 0 0 0"
unix_time = mktime(date_for_mktime)
}
unix_time > 0 {
$NF = strftime("%A", unix_time)
}
always {print $current_record}' your-file
Если вы хотите, чтобы названия дней недели всегда были на английском языке, независимо от локали пользователя, вы можете исправить локаль наC
(LC_ALL=C gawk...
).
С помощью "одного -лайнера" наверное нельзя (Редактировать :оказалось можно, всё-таки ), но можно сделать это с помощью шелл-скрипта. Ядром является использование утилиты date
для получения дня недели из даты, которую вы уже извлекли.
Для этого посмотрите на вывод
user@host $ date +%A -d 2019-07-14
Sunday
Используя это, вы можете написать сценарий, который считывает строку входного файла -, извлекает день недели для каждой строки, кроме заголовка, и записывает заголовок без изменений, а все остальные строки с днем недели добавляются в другой файл.
#!/bin/bash
# Check if input and output filenames were specified
if [[ "$#" != "2" ]]
then
echo "Usage: $0 <input filename> <output filename>"
exit 1
fi
if [[ ! -e "$1" ]]
then
echo "Error, $1 doesn't exist!"
exit 1
fi
if [[ "$1" == "$2" ]]
then
echo "Error, input and output filenames must not be equal!"#
exit 1
fi
# Perform the actual transformation
while read input
do
if [[ -n "$(grep "^Server" <<< $input)" ]]
then
echo "$input" > $2
else
date=$(awk '{match($0,",(20[[:digit:]]{2}-[[:digit:]]{2}-[[:digit:]]{2})",a); print a[1]}' <<< $input)
wday=$(date +%A -d $date)
echo "$input$wday" >> $2
fi
done < $1
Первая часть — это проверки работоспособности ввода, они также могут выполняться иначе.
Вторая часть — это реальный цикл по строкам входного файла.
grep
, чтобы определить, начинается ли она со строки «Сервер». Если результатом grep
является непустая строка -, запишите ее в выходной файл «как есть». awk
, чтобы найти шаблон «20YY -MM -DD», заключенный в запятую, и извлечь фактическое значение во внутренний массив a
, который назначен переменной bash $date
. date
, как указано выше, для возврата дня недели. С Миллер(mlr
):
mlr --csvlite put '
$Hour = ""; $DOW = strftime(strptime($Datestamp,"%Y-%m-%d"),"%A")
' file.csv
Пр.
$ mlr --csvlite put '$Hour = ""; $DOW = strftime(strptime($Datestamp,"%Y-%m-%d"),"%A")' file.csv
Server ID,Make,"Server Room",Datestamp,Timestamp,Distance,Ping,Download,Upload,Payload,"Src IP Address",Hour,DOW
x6883101,HP,"Server Room A",2019-07-14,04:50:02,26.444,11.521,49193480,41904833,,192.168.1.1,,Sunday
s3398577,Dell,"Server Room B",2019-09-21,10:50:02,56.574,37.608,48955461,45858381,,192.168.1.1,,Saturday
x6883551,Dell,"Server Room A",2019-08-16,02:00:04,26.444,17.921,86551957,88775986,,192.168.1.1,,Friday
s1555023,HP,"Server Room C",2018-02-06,04:50:01,516.574,402.527,907658,608152,,192.168.1.1,,Tuesday
s3398023,HP,"Server Room B",2019-01-17,10:50:01,56.574,40.233,48484827,45620028,,192.168.1.1,,Thursday
s1555098,IBM,"Server Room C",2018-11-18,02:00:03,516.514,404.671,819027,601233,,192.168.1.1,,Sunday
x6883582,Dell,"Server Room A",2019-05-19,04:50:02,26.444,12.506,88871436,84360552,,192.168.1.1,,Sunday
Пакет miller
доступен в репозитории Ubuntu 16.04 universe
.
Моя первая реакция была такой же, как у Стефана.
Perl тоже подойдет:
perl -MTime::Piece -F, -lape '
if ($F[3] =~ /^[\d-]+$/) {
$F[-1] = Time::Piece->strptime($F[3], "%Y-%m-%d")->strftime("%A");
$_ = join ",", @F;
}
' file