Определение нескольких переменных одновременно (копирование-вставка-выполнение в оболочке)

perl -alF'/\n[}{]\n/' -0777ne '
   for ( 0.. $#F/2 ) {
      my $i = 2*$_;
      my($k,$v) = @F[$i,$i+1];
      if ( exists $h{$k} ) {
         $h{$k}.= join $\, grep { ! exists $seen{$k,$_} } split $\, $v;
      } else {
         push @k, $k;
         $seen{$k,$_}++ for split $\, $h{$k} = $v;
      }
   }
   print "$_\n{\n$h{$_}\n}" for @k;
' yourfile

Результаты

abcd/efgh/a.jar
{
abcd/efgh/a.class
cdef/ghij/b.class
klmn/opqr/c.class
}
lkmn/opqr/b.zip
{
abcd/efgh/a.class
cdef/ghij/b.class
}

Работа

Входной файл обрабатывается, а затем разбивается на поля на основе разделителя полей, указанного в опции -F. Мы получим четное количество элементов в массиве @F. Затем четные номера используются как ключи хеша %h, в то время как их соответствие. значения берутся из следующего нечетного значения.

Хэш %hзаполняется путем разделения элементов с нечетными номерами на разделитель записей ($\ = \n ). В то же время мы помещаем ключ в массив @k, чтобы мы могли получить элементы хеша в том порядке, в котором они были обнаружены.

Все это время используются только те нечетные элементы, которые еще не видны.

0
22.08.2019, 14:11
2 ответа

Скобки, которые вы использовали, приводят к тому, что заключенные в них команды выполняются подоболочкой; следовательно, после выхода из этой оболочки переменные de по-прежнему не устанавливаются в текущей оболочке.

Я в недоумении, почему вы думаете, что эти скобки устанавливали бы эти переменные "за один раз", или зачем нужно было бы им их "за один раз"; однако вы можете поместить эти назначения в одну строку, например:

var1="myvar1" var2="myvar2"

Конечно, нет причин не копировать и не вставлять эти строки все вместе в одну пасту, как прокомментировал Аркадиуш Драбчик, если это проще и все, что вы хотите сделать.

1
28.01.2020, 02:22

Вам не нужно копировать их одну за другой, вы можете вставить все строки вместе, и новые строки будут работать как Enter.

Причина, по которой

(
var1="myvar1"
var2="myvar2"
)

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

(
var1="myvar1"
var2="myvar2"
echo $var2
)

Это объясняется в разделе Commpound Commandsв man bash:

.

Compound Commands

A compound command is one of the following. In most cases a list in a command's description may be sepa- rated from the rest of the command by one or more newlines, and may be followed by a newline in place of a semicolon.

(list) list is executed in a subshell environment (see COMMAND EXECUTION ENVIRONMENT below). Variable assignments and builtin commands that affect the shell's environment do not remain in effect after the command completes. The return status is the exit status of list.

Далее также говорится:

{ list; } list is simply executed in the current shell environment. list must be terminated with a newline or semicolon. This is known as a group command. The return status is the exit status of list. Note that unlike the metacharacters ( and ), { and } are reserved words and must occur where a reserved word is permitted to be recognized. Since they do not cause a word break, they must be separated from list by whitespace or another shell metacharacter.

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

{
var1="myvar1"
var2="myvar2";
}

Я вижу, вы задаете много простых вопросов о Bash. Рассмотреть возможность прочтите несколько руководств по Bash, man bashи узнайте об общих Bash подводные камни .

3
28.01.2020, 02:22

Теги

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