Когда у вас возникают подобные вопросы, лучше всего обратиться к man-страницам. Посмотрите на страницу rpm
man.
$ man rpm
...
-E, --eval='EXPR'
Prints macro expansion of EXPR.
Поняв, что %fedora
- это макрос, если вы пройдете немного дальше по странице rpm
man, то увидите, в каких файлах содержатся определения макросов.
Macro Configuration
/usr/lib/rpm/macros
/usr/lib/rpm/redhat/macros
/etc/rpm/macros
~/.rpmmacros
Заглянув внутрь /etc/rpm/macros
, вы увидите это определение.
$ grep fedora /etc/rpm/macros*
/etc/rpm/macros.dist:%fedora 19
Итак, мы видим, что есть определение под названием %fedora
и на моей системе (Fedora 19) оно имеет значение "19".
Обозначение $(...)
выполнит любую команду, которая находится между скобками, и подставит вместо нее возвращенные результаты.
$ echo $(echo hi)
hi
Или в вашем случае:
$ echo $(rpm -E %fedora)
19
Итак, когда выполняется команда, о которой вы спрашиваете, происходят следующие вещи. Макрос RPM, %fedora
, оценивается с помощью команды rpm
. Эта команда выполняется в строке. После расширения до "19" это значение используется в более крупной команде yum
для установки соответствующего файла .rpm
для данной версии Fedora.
I am new to Linux and I being trying to covert the date format
Intente utilizar date
con el interruptor -d
:
-d, --date=STRING display time described by STRING, not 'now'
Y luego formatee la salida de la manera que desee.
Ejemplo:
date -d "12/6/2013 10:26:32 AM" "+%F %H:%M:%S"
2013-12-06 10:26:32
Para obtener una explicación del formato, consulteman date
(la sección FORMAT
).
Escribí un script de Python y un script de Bash que deberían hacer lo que quieras.
Aquí hay una secuencia de comandos de Python que convierte todos los campos de tiempo -de un formato a otro, como se especifica en la pregunta:
#!/usr/bin/env python3
# -*- coding: ascii -*-
"""reformat_time.py
Change date format from:
MM/DD/YYYY HH:MM:SS am/pm
to:
YYYY-MM-DD HH:MM:SS
in a CSV file
"""
import csv
from datetime import date
from datetime import datetime
import sys
# Open the file (taken as a command-line argument)
with open(sys.argv[1], 'r') as csvfile:
# Parse the CSV data
csvreader = csv.reader(csvfile, delimiter=',', quotechar='"')
# Iterate over the rows
for row in csvreader:
# Iterate over the columns of each row
for index, col in enumerate(row):
# Try to parse and convert each column
try:
_datetime = datetime.strptime(col, "%m/%d/%Y %H:%M:%S %p")
newcol = _datetime.strftime("%Y-%m-%d %H:%M:%S")
# If parsing fails, leave the column unchanged
except ValueError:
newcol = col
# Update the column value
row[index] = newcol
# Output the updated row
print(','.join(row))
Supongamos que su archivo CSV se llama data.csv
y contiene la siguiente línea (tomada de su publicación):
Victor,5555555,12/6/2013 10:26:32 AM,Colosseum,1,12/8/2013 1:05:45 PM
Entonces podrías ejecutar el script así:
python reformat_time.py data.csv
Esto produciría el siguiente resultado:
Victor,5555555,2013-12-06 10:26:32,Colosseum,1,2013-12-08 01:05:45
Y aquí hay un script Bash que usa la utilidad GNU date
que tiene (casi )el mismo efecto:
#!/bin/bash
# reformat_time.sh
# Loop over the lines of the file
while read -r line; do
# Extract the field values for each row
Name="$(echo ${line} | cut -d, -f1)";
Phone="$(echo ${line} | cut -d, -f2)";
SalesDate="$(echo ${line} | cut -d, -f3)";
Venue="$(echo ${line} | cut -d, -f4)";
NoOfUnits="$(echo ${line} | cut -d, -f5)";
ModifiedDate="$(echo ${line} | cut -d, -f6)";
# Convert the time-fields from the old format to the new format
NewSalesDate="$(date -d "${SalesDate}" "+%Y-%m-%d %H:%M:%S")";
NewModifiedDate="$(date -d "${ModifiedDate}" "+%Y-%m-%d %H:%M:%S")";
# Output the updated row
echo "${Name},${Phone},${NewSalesDate},${Venue},${NoOfUnits},${NewModifiedDate}";
done < "$1"
Podría ejecutarlo así:
bash reformat_time.sh data.csv
Y produciría el siguiente resultado:
Victor,5555555,2013-12-06 10:26:32, Colosseum,1,2013-12-08 13:05:45
Tenga en cuenta que el script Bash es mucho más frágil. No maneja errores -y solo afecta los campos 3 y 6. También conserva el espacio en blanco -que rodea el separador de campo, lo que no hace la secuencia de comandos de Python anterior.
Puedes probar con este awk
awk -F, '
function cvtdate( dat, array) {
split(dat,array,"/| |:")
array[4]=array[7]=="PM"?(array[4]+12):array[4]
return array[3]"-"array[1]"-"array[2]" "array[4]":"array[5]":"array[6]
}
{
$3=cvtdate($3)
$6=cvtdate($6)
}1' OFS=',' infile
Otro posible awk oneliner:
awk -F, '{ a[3];a[6] ; for (i in a) "date -d \""$i"\" \"+%Y-%m-%d %H:%M:%S\"" |& getline $i }1' OFS=, filename
No hay necesidad real de llamar date
. Como los únicos cambios son ordenar y agregar 12 (horas )a un campo, awk podría hacerlo todo:
awk -F, 'BEGIN{ f[1]=3; f[2]=6; regex="[^/: ]+" }
NR>1{
for (i in f){
patsplit($f[i], a, regex)
b="%s-%s-%s %s:%s:%s"
c=(a[4]+((a[7]=="PM")?12:0))
$f[i]=sprintf(b,a[3],a[2],a[1],c,a[5],a[6])
}
} 1' OFS=, infile