Разбор файла на блоки и повторение каждого блока

$ awk -v FS="'" -v OFS="\t" 'FNR==3 && NF>2 {print FILENAME, $2; nextfile}' *.txt |parallel --colsep "\t" 'mv {1} {2}'

awkперебрать все файлы в расположении. Мы определяем 'как разделитель полей. Всякий раз, когда он достигает третьей строки и есть более 2 полей (, что должно быть, если у нас есть два '), он печатает имя файла и второе поле (, которое является частью между первыми двумя')с разделителями. по вкладке. Затем он переходит к следующему файлу.

Результат передается в parallel. parallelвыполнить команду mv, заменив {1}и {2}значениями, указанными в столбцах результата awk.

Некоторые примечания:

  • nextfileдоступен не во всех версиях awk
  • Пробелы в имени файла никогда не были хорошей идеей. Вы можете заменить их символом подчеркивания, если измените команду awkследующим образом:

    awk -v FS="'" -v OFS="\t" 'FNR==3 && NF>2 { gsub(" ", "_", $2); print FILENAME, $2; nextfile}' *.txt

  • Вам следует переместить или скопировать новые имена файлов в другую папку. Я не уверен, как awkотреагирует, если новые файлы появятся в той же папке во время выполнения.
0
27.01.2021, 16:14
2 ответа
$ cat tst.awk
/^Block name/ { name = $NF }
/END/ {
    for (var in var2val) {
        printf "%s has a var named %s and its value is %s\n", name, var, var2val[var]
    }
    delete var2val
}
NF==2 { var2val[$1] = $2 }

$ awk -f tst.awk file
Block1 has a var named var1 and its value is 32.7
Block1 has a var named var2 and its value is 12.2
Block1 has a var named var3 and its value is 65.4
Block43 has a var named foo3 and its value is 23.4
Block43 has a var named bar55 and its value is 654.555
Block66 has a var named bar2 and its value is 33.0987
1
18.03.2021, 22:34

Вот так:

$ awk '/^Block/{block=$1}
       /foo/{
          printf "The value of foo in %s is : %s\n",block,$2
       }' file
The value of foo in Block1 is : 5423
The value of foo in Block2 is : 6435907
The value of foo in Block3 is : 353321111
The value of foo in Block4 is : 9876543210

Или, если у вас может быть несколько строк, начинающихся с Block, и вам нужна только одна сразу после BEGIN, вы можете использовать:

awk '/BEGIN/{a=1}
     /END/{a=0} 
     /^Block/ && a{
        block=$1; 
        a=0
     } 
     /foo/{
       printf "The value of foo in %s is : %s\n",block,$2
     }' file 
1
18.03.2021, 22:34

Теги

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