'xargs' с пробелами в именах файлов

Это не имеет значения потому что оба 4>&1 и 4<&1 сделайте то же самое: dup2(1, 4) который является системным вызовом для дублирования fd на другого. Дублированный fd автоматически наследовал направление ввода-вывода исходного fd. (то же для 4>&- по сравнению с 4<&- который обе твердости к close(4), и 4>&1- который является dup2(1, 4) сопровождаемый close(1)).

Однако 4<&1 синтаксис сбивает с толку, если по некоторым причинам fd 1 не был явно открыт для чтения (который будет еще более сбивать с толку), таким образом, в моем уме должен будет избежаться.

Дублированный fd совместно использует то же открытое описание файла, что означает, что они совместно используют то же смещение в файле (для тех типов файлов, где это имеет смысл), и те же связанные флаги (режим перенаправления/открытия ввода-вывода, O_APPEND и так далее).

На Linux существует другой способ копировать a fd (который не является действительно дублированием), и создайте новое открытое описание файла для того же ресурса, но с возможно различными флагами.

exec 3> /dev/fd/4

В то время как на Солярисе и вероятно большинстве других Нельдов, который более или менее эквивалентен dup2(4, 3), на Linux, который открывает тот же ресурс как, на который указывает fd 4 с нуля.

Это - важное различие, потому что, например, для регулярного файла, смещение fd 3 будет 0 (начало файла), и файл будет усеченным (который является, почему, например, на Linux необходимо записать tee -a /dev/stderr вместо tee /dev/stderr).

И режим I/O может отличаться.

Интересно, если fd 4 указал на конец чтения канала, то fd 3 теперь указывает на конец записи (/dev/fd/3 ведет себя как именованный канал):

$ echo a+a | { echo a-a > /dev/fd/0; tr a b; }
b+b
b-b

$ echo a+a | { echo a-a >&0; tr a b; }
bash: echo: write error: Bad file descriptor
b+b
7
13.04.2017, 15:36
5 ответов

У меня есть два предсказания нефти, которые могут помочь. Однако не чувствует, что, возможно, что-то лучше придут.

Во-первых, используйте SED, чтобы добавить цитаты всему, поэтому вы покончите только в том случае, если есть только какие-то котировки в имени файла, такое как

ls -t | head -500 | sed -e 's/\(.*\)/"\1"/' | xargs file | grep -v 'image'

, другой - использовать LS, чтобы найти 501-е место Чтобы получить более новые вещи, как

find -newer $(ls -t | head -501 | tail -1) -type f -exec file {} \; | grep -v image
1
27.01.2020, 20:17

Для общих советов относительно обработки имен файлов, потенциально содержащих пробелы, см. Почему мой скрипт Shell заслонка пробела или других специальных символов?

Трудность с тем, что вы пытаетесь Для этого нет хорошего способа перечислить самые последние файлы со стандартными инструментами.

Самый простой способ сделать то, что вы делаете здесь, - это использовать ZSH как ваша оболочка. Он имеет квалификаторы для сортировки файлов по дате. Для запуска файл в 500 последних файлах:

file *(om[1,500])

с файлом Linux Утилита, пропустите -I или - Тип MIME Опция, чтобы получить вывод, который легче разбираться. Файлы изображения идентифицируются по линиям, заканчивающимся с изображением / что-то .

file --mime-type *(om[1,500]) | sed -n 's~: *image/[^ ]*$~~p'

Если вам нужно справиться с абсолютно всеми именами файлов, в том числе с новой строкой в ​​их имени, используйте опцию -0 для вывода NULL-DELIMITED. Последние версии GNU SED могут использовать NULL BYTES в качестве разделителя записи вместо новых линий.

file --mime-type -- *(om[1,500]) | sed -zn 's~: *image/[^ ]*$~~p'

Если у вас нет ZSH, вы можете использовать LS и справиться с именами файлов, которые содержат пробелы, но не в номинальные или конечные пробелы, передавая опцию -L1 , чтобы Файл . Это вызвало файл в одном файле одновременно, поэтому он немного медленнее.

ls -t | head -n 500 | xargs -L1 file --mime-type -- | sed -n 's~: *image/[^ ]*$~~p'
1
27.01.2020, 20:17

Использование Xargs , это можно сделать таким образом:

find . -type f -print0 | xargs -0 file | grep -v 'image' 

Но вчера настолько вчера. Крутые дети используют Parallel сегодня. Используя параллельно, это было бы:

find . -type f | parallel file | grep -v 'image'

см. Без использования -Print0 и -0. Параллель действительно умно сам.

Обновление

Для листинга только последних 500 файлов ваша команда будет:

ls -1t | head -500 | parallel file {} | grep -v image

важно

в случае, если ваш параллель старый и выше синтаксис не работает, то установите новую версию параллельно как Знаменил здесь: http://www.gnu.org/software/parallel/parallel_tutorial.html

5
27.01.2020, 20:17

Используйте "find" с опцией "-print0", а вывод - "xargs" с опцией "-0".

Несмотря на то, что я знаю (и использую) эту технику, я вижу, что пользователь @Jens ответил на похожий вопрос, где вы можете найти более подробную информацию :

https://stackoverflow.com/questions/16758525/use-xargs-with-filenames-containing-whitespaces

2
27.01.2020, 20:17

Можно попробовать

printf "%s\0" $(ls -t | head -500) | xargs -0 file | grep -v image

Это заставляет xargs свести к нулю аргументы имени файла.

-1
27.01.2020, 20:17

Теги

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