Преобразование результатов оболочки в файл Excel в столбцах

При циклическом обходе каталогов, особенно если у них странные имена, не повторяйте вывод ls. В общем, передача путей между программами должна выполняться с большой осторожностью, поскольку имена файлов Unix могут содержать любые символы, кроме /и нулевого символа(\0).

Вместо

for dirname in./*/; do
    printf 'Directory name is "%s"\n' "$dirname"
done

Последнее /в шаблоне ./*/расширяет шаблон только до каталогов. При этом переменная dirnameполучит такие значения, как ./some directory name/. Я включил ./в начале паттерна, но вы можете удалить его, если хотите. Просто имейте в виду, что если у вас есть каталоги, в именах которых есть тире(-)в качестве первого символа, вам позже придется использовать, например,.mv -- "$dirname" "$newname"--), чтобы mvне интерпретировал тире в имени как параметр командной строки. При ./в начале $dirname--не требуется.

Очень особенно важно заключать расширения переменных в кавычки, так как в противном случае оболочка будет выполнять разбиение на слова и подстановку имен файлов в значениях.

Связанные:

1
10.08.2020, 03:49
3 ответа

Учитывая модификацию вашего образца ввода:

$ cat input
Host                                            Status       Expires      Days
----------------------------------------------- ------------ ------------ ----
FILE:certs/dnscert1.crt                         Valid        Aug  1, 2020  7
FILE:certs/dnscert2.crt                         Invalid      Aug  4, 2021  359
FILE:certs/dnscert3.crt                         Valid        Aug  4, 2021  359

Затем, если я применю следующую команду awk, я получу:

$ awk 'NR > 2 { print $1 "," $2 ",\"" $3, $4, $5 "\"," $6}' input
FILE:certs/dnscert1.crt,Valid,"Aug 1, 2020",7
FILE:certs/dnscert2.crt,Invalid,"Aug 4, 2021",359
FILE:certs/dnscert3.crt,Valid,"Aug 4, 2021",359

Предполагается, что поле даты всегда состоит из 3 токенов :месяца, дня и года.

NR > 2пропускает первые две строки :заголовка и разделителя. Остальные просто печатают поля с запятыми между ними, стараясь указать поля даты.

0
18.03.2021, 23:13

Предполагая, что сценарий оболочки предоставляет данные с пробелами для разметки, вы можете использовать awk для преобразования в разделенную вкладку -. Excel откроет вкладку -файл с разделителями (, возможно, жалуясь на несоответствие формата ), и при необходимости позволит пользователю сохранить как xlsx.

$my_script | awk -v OFS='\t' '{$1=$1}1' > myexcel.xls

В котором используется трюк, чтобы принудительно использовать OFS, а затем печатать. Или менее загадочный:

$my_script | '{print $1 "\t" $2 "\t" $3 "\t" $4}' > myexcel.xls

Существуют модули для ваших любимых языков сценариев, которые будут создавать «настоящий» файл xlsx (, который представляет собой просто заархивированный каталог XML ), но это более сложно. Если вам просто нужно что-то, что пользователи могут щелкнуть и открыть в Excel, отлично подойдет вкладка -, разделенная расширением xls..

0
18.03.2021, 23:13

Поля сами содержат пробелы, как и поле даты, поэтому нам нужно разработать другую стратегию.

Используя заголовок (, предполагая, что в именах полей нет пробелов, )получите ширину каждого поля и вставьте ее в FIELDWIDTHS, встроенную -в переменную awk, во втором проходе по входному файлу.

$ fw=$(< file \
   awk -v FPAT='[^[:space:]]+([[:space:]]+|$)' '  NR>1{exit}
{for (i=1; i<=NF; i++) $i=length($i)}1')

$ awk \
  -v q=\" -v OFS=,     \
  -v FIELDWIDTHS="$fw" \
'
function trim(a,  l, t) {
  l = "^[[:space:]]+"
  t = "[[:space:]]+$" 
  re = l "|" t
  gsub(re, "", a)
  return a
}
function quote(a,  r, nondigit) {
  r = "[^[:digit:]]"
  nondigit = a ~ r
  return nondigit ? q a q : a
}
NR==2{next} 
{
  for (i=1; i<=NF; i++) {
    t = $i
    gsub(/"/, "\\&", t)
    t = trim(t)
    $i = quote(t)
  }
}1' file

"Host","Status","Expires","Days"
"FILE:certs/dnscert.crt","Valid","Aug  4, 2021",359
0
18.03.2021, 23:13

Теги

Похожие вопросы