Первый выпуск:
Если вы поместите *
в оболочку напрямую, не заключая ее в кавычки, она будет расширена оболочкой до списка файлов в текущем каталоге еще до того, как команда будет выполнена.
Второй выпуск:
grep
по умолчанию использует регулярные выражения для сопоставления шаблонов. В регулярном выражении *
означает «соответствовать шаблону ноль или более раз», а точка(.
)означает «соответствовать любому символу».
Итак, вы хотите что-то вроде:grep ".*" filename
. Или просто используйте кошку
Переменные не раскрываются в строках с одинарными кавычками. Нет никакого способа обойти это.
В этом случае вы хотите вывести три первые строки ваших данных как есть, а остальные отсортировать. Для простоты я бы сделал это с
sort_opts=( -k3,3r -k2,2 -k1,1r )
{ head -n 3 file
awk 'NR > 3' file | sort "${sort_opts[@]}" -t '~' } >newfile
Если вы чувствуете, что действительно хотите выполнить сортировку изнутри awk
и предполагая, что $IFS
остается неизменным с пробелом в качестве первого символа:
sort_opts=( -k3,3r -k2,2 -k1,1r )
awk -v sort_opts="${sort_opts[*]}" '
BEGIN { sortcmd = sprintf("sort %s -t \"~\"", sort_opts) }
NR <= 3 { print; next } { print | sortcmd }' file >newfile
Это дает параметры сортировки для awk
с использованием -v
в командной строке, блок BEGIN
создает команду сортировки для использования в качестве строки в переменной sortcmd
, и затем она используется в последнем блок (срабатывает для линий 4 в -подопечных ).
Обратите внимание, что при использовании print
с каналом в awk
правая часть канала должна быть строкой, представляющей команду оболочки для передачи по каналу. В вашем коде это не так, поэтому вы получаете ошибку «недопустимое утверждение».
Если значения, которые необходимо импортировать в awk
, содержат обратную косую черту, вы можете вместо этого использовать переменную среды (, чтобы не удваивать каждую обратную косую черту):
sort_opts=( -k3,3r -k2,2 -k1,1r )
SORT_OPTS="$sort_opts[*]" awk '
BEGIN { sortcmd = sprintf("sort %s -t \"~\"", ENVIRON["SORT_OPTS"]) }
NR <= 3 { print; next } { print | sortcmd }' file >newfile