Как расширить слово в bash? Не говоря уже о подстановочных знаках файлов

Оптимизированное отдельное -обработанное GNU Awk решение:

awk 'BEGIN{ PROCINFO["sorted_in"]="@ind_str_asc" }
     { a[$NF]=$0 }END{ for(i in a) print a[i] }' unsortedNames.txt

  • PROCINFO["sorted_in"]="@ind_str_asc"-сравнение/сортировка по ключам/индексам массива. Мы можем установить предопределенный массив PROCINFOв одно из набора предопределенных значений. Эти специальные значения описаны здесь (документация):https://www.gnu.org/software/gawk/manual/gawk.html#Controlling-Scanning

Выход:

I M Board
Lenny R Graph
Faye King
Grey White

2
17.07.2020, 03:47
2 ответа

Я думаю, вы ищете это:

eval "echo $(cat file)"

eval создает команду, которая затем выполняется оболочкой.

1
18.03.2021, 23:19

Вы просто используете не тот инструмент для работы:

[user@host dir]$ ksh
$ echo "{1..4}" > file
$ cat file
{1..4}
$ echo $(<file)
1 2 3 4
$ echo $(cat file)
1 2 3 4

Шутки в сторону, порядок расширений в Bash такой:

  1. расширение расчалки;
  2. расширение с помощью тильды, расширение параметров и переменных, арифметическое расширение и подстановка команд (, выполненные слева -в -справа );
  3. разбиение слов;
  4. и расширение имени файла.

Таким образом, в echo $(cat file)выходные данные подстановки команды (без кавычек )подвергаются только разбиению на слова и расширению имени файла, оставаясь неизменными, поскольку не включают символы сопоставления с образцом (и предполагают, что ваш IFSпеременная не включает {, 1, ., 4или}).

Хотя некоторые расширения могут быть вложенными, результат расширения, как правило, не анализируется повторно на наличие символов, которые запускают раскрытия от этапов до текущего. (По уважительной причине :подумайте оfoo=\$foo; echo "$foo").

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

$. <(printf '%s ' echo; cat file)
1 2 3 4

Обратите внимание, что в обоих случаях все содержимое fileбудет проанализировано и выполнено в текущей среде.

Аналогично, но выполнение в отдельной среде нового bashпроцесса:

$ bash <<<$( printf "%s " echo; cat file; )
1 2 3 4

Между прочим, ksh93 (оболочка, которую я использовал в своем первом блоке кода )ведет себя особым образом :раскрытие скобок выполняется на более позднем этапе, как часть разделения полей, и результат предыдущие расширения анализируются заново для обнаружения фигурных скобок 1:

$ bash -c 'echo {1..$(printf %s 3)}' mybash
{1..3}
$ ksh -c 'echo {1..$(printf %s 3)}' myksh
1 2 3

1Как заметил Stéphane Chazelas в комментариях , такое поведение ksh93 можно считать ошибкой и оно не соответствует POSIX.так как это позволяет $varне расширяться до значения var.

3
18.03.2021, 23:19

Теги

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