проанализировать список файлов в каталоге и сохранить в новую папку

Существует разница в том, как Bash и Dash обрабатывают ввод со стандартного ввода. :При запуске команды(suздесь )Bash заботится о том, чтобы оставить позицию чтения на стандартном вводе сразу после строки, вызвавшей запуск команды, либо считывая побайтно для каналов, либо возвращаясь назад, если ввод из файла. Dash это не волнует, он просто читает полные блоки.

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

Таким образом, с Bash он читает su test\nwhoami\n, выполняет поиск сразу после первой новой строки, затем запускает su, который теперь видит whoami\nна входе.

С Dash он читает su test\nwhoami\n, запускает su, который не видит ввода и завершает работу, а затем Dash запускает whoami.


Вы можете видеть то же самое здесь, с Dash, команда dateвыполняется и readполучает пустой ввод, а с Bash эта строка от readдо x.

$ cat test.sh
read x
date
echo "variable x = '$x'"
$ cat test.sh | bash
variable x = 'date'
$ cat test.sh | dash
Sat Aug 24 12:25:23 EEST 2019
variable x = ''

Если я правильно интерпретирую POSIX-описание sh, требуется осторожное поведение Bash, а более слабый подход Dash не соответствует этому:

STDIN
[...] When the shell is using standard input and it invokes a command that also uses standard input, the shell shall ensure that the standard input file pointer points directly after the command it has read when the command begins execution. It shall not read ahead in such a manner that any characters intended to be read by the invoked command are consumed by the shell

Что бы это ни стоило, оболочка Busybox ведет себя здесь как Dash, все остальные, которые я тестировал, ведут себя так же, как Bash.

-2
05.10.2021, 23:35
1 ответ

Используйте здесь только awk:

gawk -v map='[GI]>H,B>E,[TS ]>C' '
BEGIN  { nrf=split(map, tmp, /[,>]/); FIELDWIDTHS="5 5 1 1 4 1 *" }

$4=="A"{ buf= buf $6 }

ENDFILE{
    for(i=1; i<=nrf; i+=2) gsub(tmp[i], tmp[i+1], buf);
    print buf >FILENAME".output"; close(FILENAME".output"); buf=""
}'./*.dssp

Здесь в -v map='[GI]>H,B>E,[TS ]>C'мы передаем преобразование отображения символов в awk (, каждый из которых разделен запятой; >также используется для большей удобочитаемости между каждой группой сопоставления )в качестве переменного параметра.

затем внутри блока BEGIN{} мы разделили отображение, полученное из переменной map, во временный массивtmpи рассмотрели эти ,и >как разделители; мы также определили поля с помощью FIELDWIDTHS (GNU awk ).

Затем мы проверяем, равно ли 4 е поле символу "A", если да, то буферизуем 6 е поле в режиме добавления из каждой строки вbuffПеременная.

в конце каждого входного файла мы обрабатываем блок ENDFILE{} (GNU awk ), и здесь мы делаем цикл по сопоставлению пар символов и заменяем левые -символы их правыми -руки в переменной buff; и после этого мы печатаем обновленное содержимоеbuffв выходной файл с тем же именем, что и вход, с добавленным суффиксом, например «fileName.output».

3
06.10.2021, 03:16

Теги

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