/usr/bin/truncate: Слишком длинный список аргументов

Вы можете использовать sed для выполнения своей задачи

sed -e 's/^.\{32\}//;s/".*//' filename.txt

Это удаляет первые 32 символа и удаляет все после первого ".

Эти замены будут происходить в каждой строке файла. Чтобы применить это к определенной строке, используйте это:

sed -e 'linenumber{s/^.\{32\}//;s/".*//;}' filename.txt

где linenumber— любое число.

linenumber{          # on the linenumber-th line, do the following
 s/^.\{32\}//        #  remove the first 33 characters
 s/".*//             #  remove the first quote and everything following it
}
2
25.08.2019, 23:15
2 ответа

Просто добавил примечание к отличному ответу @ilkkachu, чтобы объяснить логику. Команда

truncate -s 1k {1..1000000}

вызывает truncateс одним миллионом аргументов плюс три (truncate(argv[0]), -sи 1k), что значительно превышает ограничение по умолчанию совокупного числа и размера аргументов и переменных среды для execve()системный вызов в большинстве систем. Отсюда и ошибка "Слишком длинный список аргументов" .

Вместо этого предлагаемое решение

seq 1 1000000 | xargs truncate -s 1k

просто запускаетtruncate(черезxargs)столько раз, сколько необходимо, с таким количеством аргументов (, кроме truncate, -sи 1k, которые повторяются при каждом вызове ), насколько это возможно, чтобы избегайте этого ограничения системного вызова execve().

2
27.01.2020, 21:55

Вы могли бы сделать

echo {1..1000000} | xargs truncate -s 1k

(Это должно работать с оболочкой со встроенным эхом, на которое не распространяются ограничения на длину командной строки. Также xargsпо умолчанию разбивает ввод на любые пробелы, но здесь это не имеет значения.)

Приведенное выше может использовать ужасное количество памяти, поэтому лучше использовать seq, как в комментарии mosvy:

seq 1 1000000 | xargs truncate -s 1k

Обычно я использую цикл, (он начинается с 000000, а не 1, и во всех именах есть ведущие нули):

for i in {000..999}; do
    touch "$i"{000..999}
done

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

for i in {000..999}; do
    mkdir "$i"
    touch "$i"/{000..999}
done

Обратите внимание: если вы не можете создать файлы, потому что они не помещаются в одну командную строку, и каким-то образом обойти это, вы, вероятно, также не сможете удалить их с помощью rm -f *. Вам нужно будет рекурсивно удалить все дерево или сделать что-то вроде find -maxdepth 1 -type f -delete.

3
27.01.2020, 21:55

Теги

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