Чтобы обрезать файл на 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
(здесь используется встроенная команда cat
ksh93
, так как некоторые другие реализации 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"
Похоже, вы ожидаете, что $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