Перестройте файл так, чтобы он был легко читаем

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

#!/usr/bin/perl

use strict;
use warnings;

my %files;
my $dir;
my @extensions = ("\.tis","\.are","LM\.bmp","\.wed");

opendir($dir, ".") || die "Error opening dir\n";
while (my $file = readdir($dir)) {
    foreach my $ext (@extensions) {
        if ($file =~ /^(.*)$ext$/sm) {
            $files{$1} += 1;
        }
    }
}
closedir($dir);

foreach my $file (keys %files) {
    if ($files{$file} == scalar(@extensions)) {
        print "$file\n";
    }
}
4
25.01.2017, 23:23
6 ответов

Самосчетная версия, сезон по вкусу:

awk '    $1!=last {n=0;last=$1}
         {++n;gaggle[n]=gaggle[n]"\n"$0}
         END { for (k in gaggle) print gaggle[k] }
'
13
27.01.2020, 20:44

Вот еще один подход в awk .

awk '{a[(NR-1)%7]=a[(NR-1)%7]$0RS}END{for(;i<7;){print a[i++]}}'

Name                : WiFi 1
MAC                 : aa:aa:aa:aa:aa:aa
IP                  : 10.0.1.0
Status              : Operational
Interface           : X2

Name                : WiFi 2
MAC                 : bb:bb:bb:bb:bb:bb
IP                  : 10.0.1.1
Status              : Operational
Interface           : X2
[etc]
5
27.01.2020, 20:44

Другой подход, без awk или sed , почему бы и нет:

split -a 1 -l 7 inputfile && paste -d '\n' x{a,b,c,d,e}
6
27.01.2020, 20:44

Еще один способ:

num=$(grep -c ^Name inputfile)
for((i=1; i <= num; i++)); do 
  for((j=1; j < num- 1; j++)); do 
    printf "%dp;" $((i + (j-1)*num)); 
  done; 
  printf "\n"; 
done | while read cmd; do sed -n "$cmd" inputfile; done
6
27.01.2020, 20:44

Этот сценарий выполнит задание, если я правильно понимаю требования:

#!/usr/bin/zsh

grep Name $1 > /tmp/wifinames
grep MAC $1 > /tmp/wifiMAC
# ...
# add lines for other fields here, you can store the names of files 
# in an array like ['file1', file2',..], and run a for loop printing the nth line inside the
# while loop below


i=1
n=`wc -l /tmp/wifinames|awk '{print $1}'`
# maybe you should run some tests to check if all the files
# produced by grep have equal number of entries 


while [[ $i -le $n ]]; do
    # prints nth line
    sed "${i}q;d" /tmp/wifinames
    sed "${i}q;d" /tmp/wifiMAC
    # ...
    (( i = $i + 1 ))
done
2
27.01.2020, 20:44

Для семи точек доступа с GNU sed и bash ] / ksh :

for (( i = 1; i <= 7; ++i )); do
  sed -n "$i~7p" data
  echo
done

С предоставленной информацией в data , это дает

Name                : WiFi 1
MAC                 : aa:aa:aa:aa:aa:aa
IP                  : 10.0.1.0
Status              : Operational
Interface           : X2

Name                : WiFi 2
MAC                 : bb:bb:bb:bb:bb:bb
IP                  : 10.0.1.1
Status              : Operational
Interface           : X2

Name                : WiFi 3
MAC                 : cc:cc:cc:cc:cc:cc
IP                  : 10.0.1.2
Status              : Operational
Interface           : X2

(и т. Д.)

Если мы не знаем, сколько существует точек доступа, подсчитайте строки Name :

num="$( grep -c '^Name' data )"

for (( i = 1; i <= num; ++i )); do
  sed -n "$i~${num}p" data
  echo
done

Специфичный для GNU sed синтаксис диапазона first ~ step будет

соответствовать каждому step ' -я строка, начинающаяся со строки , первая .

согласно руководству GNU sed .

10
27.01.2020, 20:44

Теги

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