Awk -Разделить каждый байт на отдельный файл, указав имя созданного файла в stdout

Помимо вышеупомянутых пунктов, вам необходимо рассмотреть еще 2 файла на удаленном сервере, к которому вы подключаетесь:

/etc/hosts.allow
/etc/hosts.deny

Вам необходимо проверить, разрешено ли ваше ssh-соединение с сервером, к которому вы подключаетесь.

Формат:

daemon:ACCESS 
daemon can be vsftpd,sshd 

если вы хотите разрешить только для определенной сети, поместите запись ниже в/etc/hosts.allow:

sshd:192.168.159.*  

(Вышеизложенное означает, что ssh-соединение разрешено для сети 192.168.159.*)

Если вы хотите ограничить доступ к определенной сети, поместите запись ниже в/etc/hosts.deny:

sshd:192.168.139.*

(Вышеизложенное означает, что ssh-соединение не разрешено для сети 192.168.139.*)

2
01.05.2020, 10:37
2 ответа

С помощью GNU awkвы можете сделать:

LC_ALL=C gawk -v RS='.{1}' '
  {
    file = "filename" ++n
    print file
    printf "%s", RT > file
    close(file)
  }' < input

Но учитывая, что он создает один файл на байт, в большинстве файловых систем у вас, скорее всего, быстро закончится место на диске (, так как файлы размером 1 -байт по-прежнему занимают несколько кибибайт дискового пространства в большинстве файловых систем )или inodes, или производительность станет ужасной после нескольких сотен тысяч входных байтов (, поскольку стоимость добавления записи в каталог увеличивается с размером каталога с несколькими реализациями файловой системы )

.
  • LC_ALL=Cозначает, что .соответствует байту, а не символу
  • RS='.{1}'устанавливает разделитель записи на 1одиночный символ (, который является одиночным байтом сLC_ALL=C). RS=.не будет работать, так как это будет означать, что разделителем записей является символ точки. Вам нужно, чтобы RSсостояло из более чем одного символа, чтобы gawkсчиталось регулярным выражением. (.)и .|.также будут работать, но в моих тестах я обнаружил, что .{1}является наиболее эффективным из 3.
  • RTсодержит текст, совпавший с RS.

RSв качестве регулярного выражения, возможность работы с двоичными данными и RTне являются стандартными расширениями -. RTявляется GNU -, специфичным для AFAIK.

4
28.04.2021, 23:16

Поскольку все, что splitделает (при создании 1-байтовых файлов, )— это нумерация файлов по порядку, но генерирует только до 256 различных файлов. Возможного содержимого файлов больше нет, всего 256.

И, поскольку преобразование многогигабайтного файла в такое же количество файлов с 1 байтом в каждом увеличит размер обрабатываемых данных в большой раз (более чем в 4000 раз в файловой системе ext4 )и сделает доступ к каждому файлу медленным.

Однако есть альтернатива, поскольку вы также говорите, что собираетесь выполнить дополнительную обработку ваших данных:

I also want the generated files to have their filename (incremented) printed to stdout, while the script is running, mostly so I can use those as variable and such in other script.

Таким образом, :гораздо более быстрым решением, которое значительно сократит потребление ресурсов, (дискового пространства, вычислительной мощности, времени и энергии ), будет:

  • Создайте 256 файлов, каждый с одним байтом от 0x00до 0xff. Это покрывает любой возможный ввод.
  • Сгенерировать в стандартном выводе a number+ a file name. Число — это позиция во входном файле с самого начала. Имя файла — это один из 256 файлов, созданных выше, чтобы дать значение байта внутри ввода.

Вы можете заранее сгенерировать 256 файлов (bash):

for((i=0;i<=255;i++)); do 
    file=prefix$(printf '%03d' "$i"); 
    printf '%b' "$(printf '\\x%x' "$i")" >$file;
done

Или просто сгенерируйте нужные при обработке многогигабайтного файла:

LC_ALL=C gawk '
  BEGIN{                                # 
      RS=".{1}"                         # set the record separator
      for(i=0;i<256;i++){
          ord[ sprintf("%c",i) ] = i    # help array ord
      }
  }
  {
    position = ++n                      # keep count of bytes read
    file = "prefix" ord[RT]             # find the file name to use
    if ( ! seen[file] ) {               # Have we seen this file ?
        printf "%s", RT > file          # If not, create it.
        close(file)                     # close the file
        seen[file]=1                    # record that we have seen it.
    }
    print position, file                # print information for next script
  }
'./input                               # file to process.

Короче :Более быстрое решение.

1
28.04.2021, 23:16

Теги

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