Как использовать переменные bash в команде awk внутри bash для

Чтобы обрезать файл на 75%, с GNU truncateвы можете сделать:

size=$(wc -c < "$file") &&
  truncate -s "$((size * 75 / 100))" -- "$file"

Сksh93:

<>; $file >#((EOF * 75 / 100))

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

command /opt/ast/bin/cat < $file <#((EOF * 25 / 100)) <>; $file

(здесь используется встроенная команда catksh93, так как некоторые другие реализации cat, такие как GNU cat, откажутся работать, если их стандартный вывод ссылается на тот же файл, что и их стандартный ввод ).

Или используйтеperl:

perl -pe '
  BEGIN{
    seek(STDIN,0,2) or die$!;
    seek(STDIN,tell(STDIN)*75/100,0) or die$!;
    $/ = \65536
  }
  END{truncate STDOUT, tell STDOUT}' < "$file" 1<> "$file"

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

.
block_size=$(stat -Lc %o -- "$file") &&
  size=$(wc -c < "$file") &&
  fallocate -cl "$((size * 25 / 100 / block_size * block_size)) -- "$file"
0
22.10.2019, 00:55
1 ответ

Похоже, вы ожидаете, что $var_i_$iрасширится до значения $var_i_1, $var_i_2и т. д. -, к сожалению, этого не происходит. Для иллюстрации предположим, что мы установили

$ var_i_1=23; var_i_2=45; var_i_3=67

, затем

$ for i in $(seq 1 3); do awk -v v_i="$var_i_$i" 'BEGIN{print v_i}'; done
1
2
3

Здесь происходит следующее: оболочка анализирует $var_i_$iкак $var_i_, объединенную с$i. Поскольку $var_i_, скорее всего, не установлен/пуст, v_iи v_fпросто наследуют значение индекса цикла i.

Существуют уродливые способы выполнения той косвенности, которую вы хотите, например.

$ for i in $(seq 1 3); do awk -v v_i="$(eval echo \${var_i_$i})" 'BEGIN{print v_i}'; done
23
45
67

однако, поскольку bash поддерживает массивы, более чистым решением было бы использовать массивы для ваших значений var_iи var_f, например.

$ var_i=(23 45 67)

затем (вспоминая, что массивы нулевые -индексированные)

$ for i in $(seq 0 2); do awk -v v_i="${var_i[i]}" 'BEGIN{print v_i}'; done
23
45
67
1
28.01.2020, 02:39

Теги

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