Как сократить команду awk и добавить начальные нули к количеству записей

#linux #awk

#linux #awk

Вопрос:

Я добавляю записи заголовка и трейлера в файл с awk командами. Как я могу сократить / консолидировать awk команду, возможно ли не использовать временные файлы и выполнять все манипуляции с исходным файлом, чтобы я мог сократить awk команду таким образом. Кроме того, мне нужно, чтобы количество записей трейлера составляло 10 байт с начальными нулями. Вот awk команда, которую я использую:

 awk -v today="$(date  %Y%m%d)" 
  -v last_day="$(date  "%Y%m%d" 
  -d "$(date  %Y-%m-01)  1 month -1 day")" 
  'BEGIN { print "ABCDEFG MC " today " FB XXX1 " today, last_day } 1' 
  original_file.txt > original_file H.txt

awk '{print} END{print "TRL" NR - 1}' 
  original_fileH.txt > original_fileT.txt

rm original_file.txt
rm original_fileH.txt
mv original_fileT.txt original_file.txt
  

Вот пример файла:

Record line 1 Record line 2

Вот результат файла после awk выполнения:

ABCDEFG MC 20201007 FB XXX1 20201007 20201031 Record line 1 Record line 2 TRL3

Комментарии:

1. Возможно, вы можете использовать sed для добавления заголовка в файл, а затем использовать echo / >> для добавления завершающих строк? Я не думаю, что вам awk это вообще нужно, потому что вы не манипулируете файлом. Если вам просто нужно посчитать строки, вы также можете использовать wc .

Ответ №1:

Если вам просто нужно добавить заголовок и хвост, вы можете просто сделать следующее:

 awk -v today="$(date  %Y%m%d)"                                              
    -v last_day="$(date -d "$(date  %Y-%m-01)  1 month -1 day")" " %Y%m%d"  
    'BEGIN { print "ABCDEFG MC",today,"FB XXX1",today, last_day }
     1; END {print "TRL", NR}' file1 > file2
mv file2 file1
  

Если у вас есть GNU awk, вы можете немного почистить его:

 awk -i inplace                                                                   
    'BEGIN{ today=strftime("%Y%m%d"); Y=substr(today,1,4); m=substr(today,5,2)
            last_day=strftime(mktime(Y" "m 1" -1 0 0 0"))
            print "ABCDEFG MC",today,"FB XXX1",today, last_day }
     1;END{print "TRL", NR}' file1
            
  

Ответ №2:

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

В основном для файла awk1 с содержимым:

 Record line 1 Record line 2
  

Мы можем использовать следующую однострочную

 cat awk1 | awk -v val1="foo" -v val2="bar" '{ print "START " val1 " MIDDLE " val2 " " $0 " END " NF }'
START foo MIDDLE bar Record line 1 Record line 2 END 6
  

В принципе, вам не нужен BEGIN или END , если вы не делаете такие вещи, как заголовки или сводки. Перенос переменных в правильные позиции здесь должен дать вам то, что вы хотите.

Комментарии:

1.Примечание: cat awk1 является UUOc (ненужное использование cat ). awk можно читать непосредственно из файла, и вы избегаете дополнительных процессов cat и канала, связывающих потоки вместе.