$ ls *mp3 | xargs mplayer
Playing Lemon.
File not found: 'Lemon'
Playing Tree.mp3.
File not found: 'Tree.mp3'
Exiting... (End of file)
Моя команда терпит неудачу, потому что файл "Lemon Tree.mp3" содержит пробелы, и поэтому xargs считает, что это два файла. Можно ли заставить find + xargs работать с такими именами файлов?
ls |grep mp3 |sed -n "7p"
тебя можно просто использоватьecho "Lemon Tree.mp3"
.Ответы:
Команда
xargs
принимает символы пробела (табуляции, пробелы, новые строки) в качестве разделителей. Вы можете сузить это только для символов новой строки ('\ n') с-d
опцией как это:Работает только с GNU xargs. Для систем BSD используйте такую
-0
опцию:Этот метод проще и работает с GNU xargs.
источник
-E
, например:xargs -E '\n'
Утилита xargs считывает строки со знаком пробела, табуляции, новой строки и конца файла из стандартного ввода и выполняет утилиту со строками в качестве аргументов.
Вы хотите избежать использования пробела в качестве разделителя. Это можно сделать, изменив разделитель для xargs. Согласно инструкции:
Такие как:
Ответить на вопрос о проигрывании седьмого mp3; проще запустить
источник
find
и GNUxargs
; не все версии этих программ поддерживают эти параметры (хотя есть основания полагать, что они должны).find
с-print0
иxargs
с-0
. AFAIK, HP-UX, AIX и Solaris, однако, этого не делают (но я исправляюсь: HP-UX 11i этого не сделал; Solaris 10 этого не сделал; AIX 5.x этого не сделал; но они не являются текущими версиями ).sed
Например, не составит труда изменить использование строк, оканчивающихся на «'\0'
вместо»'\n'
, а POSIX 2008getdelim()
облегчит управление.Пытаться
вместо того
источник
У xargs в MacOS нет опции -d, поэтому в этом решении вместо нее используется -0.
Получите ls для вывода по одному файлу на строку, затем переведите новые строки в null и скажите xargs использовать null в качестве разделителя:
ls -1 *mp3 | tr "\n" "\0" | xargs -0 mplayer
источник
В моем случае это помогло удалить разные файлы с пробелами. Это должно работать тоже с mplayer. Необходимый трюк - это цитаты. (Проверено на Linux Xubuntu 14.04.)
источник
В ответе Дика. Гуэртина [1] предполагалось, что можно избежать пробелов в имени файла, что является ценной альтернативой другим предлагаемым здесь решениям (таким как использование нулевого символа в качестве разделителя, а не пробела). Но это может быть проще - вам не нужен уникальный персонаж. Вы можете просто с помощью sed добавить экранированные пробелы напрямую:
Кроме того, grep необходим, только если вам нужны только файлы с пробелами в именах. В более общем смысле (например, при обработке пакета файлов, некоторые из которых имеют пробелы, а некоторые нет), просто пропустите grep:
Тогда, конечно, имя файла может иметь другие пробелы, чем пробелы (например, вкладка):
Это предполагает, что у вас есть sed, который поддерживает -r (расширенное регулярное выражение), такой как GNU sed или последние версии bsd sed (например, FreeBSD, в котором изначально была написана опция "-E" до FreeBSD 8, и поддерживаются оба -r & -E для совместимости). через FreeBSD 11 как минимум). В противном случае вы можете использовать скобочное выражение для базового класса регулярных выражений и вручную вводить символы пробела и табуляции в
[]
разделители.[1] Возможно, это более уместно в качестве комментария или редактирования этого ответа, но на данный момент у меня недостаточно репутации, чтобы комментировать, и я могу только предлагать правки. Поскольку последние формы выше (без grep) изменяют поведение первоначального ответа Дика. Гуэртина, прямое редактирование, возможно, в любом случае не подходит.
источник
ls | grep mp3 | sed -n "7p" | xargs -i mplayer {}
Обратите внимание, что в приведенной выше команде
xargs
вызоветmplayer
заново для каждого файла. Это может быть нежелательно дляmplayer
, но может быть хорошо для других целей.источник
mplayer
вызов для каждого файла. Это важно, если вы попробуете, например... | xargs -I{} mplayer -shuffle {}
: это будет играть в полностью детерминированном порядке, несмотря на-shuffle
.xargs
в основном используется с командами, которые принимают список имен файлов (простой пример:)rm
, и пытается передать столько имен файлов, сколько может поместиться в каждом вызове, при необходимости разделяясь только на несколько вызовов. Разницу можно увидеть, когда вы используете команду, в которой виден каждый вызов, напримерecho
(по умолчанию):seq 0 100000 | xargs
печатает все числа от 0 до 23695 (в зависимости от платформы, но это то, что происходит в моей системе) в первой строке до 45539 в строке 2 и т. д. И вы правы, для большинства команд это не имеет значения.В macOS 10.12.x (Sierra), если у вас есть пробелы в именах файлов или подкаталогах, вы можете использовать следующее:
источник
Это зависит от того, (а) насколько вы привязаны к номеру 7, в отличие, скажем, от Лимонов, и (б) от того, содержат ли какие-либо имена файлов новые строки (и хотите ли вы их переименовать, если они это сделают).
Есть много способов справиться с этим, но некоторые из них:
read
Цикл не работает , если имена файлов содержат символы новой строки; остальные работают правильно даже с символами новой строки в именах (не говоря уже о пробелах). За мои деньги, если у вас есть имена файлов, содержащие новую строку, вы должны переименовать файл без новой строки. Использование двойных кавычек вокруг имени файла является ключом к правильной работе циклов.Если у вас есть GNU
find
и GNUxargs
(? Или FreeBSD (* BSD), или Mac OS X), вы можете также использовать-print0
и-0
варианты, как в:Это работает независимо от содержимого имени (только два символа, которые не могут отображаться в имени файла, - это косая черта и NUL, и косая черта не вызывает проблем в пути к файлу, поэтому использование NUL в качестве разделителя имен охватывает все). Однако, если вам нужно отфильтровать первые 6 записей, вам нужна программа, которая обрабатывает «строки», оканчивающиеся NUL, а не перевод строки ... и я не уверен, что они есть.
Первый, безусловно, самый простой для конкретного случая под рукой; тем не менее, он может не распространяться на другие ваши сценарии, которые вы еще не перечислили.
источник
Я знаю , что я не отвечать на
xargs
вопрос прямо , но это стоит отметитьfind
«s-exec
вариант.Учитывая следующую файловую систему:
Можно найти команду find для обработки пространства в Dream Theater и King's X. Итак, чтобы найти барабанщиков каждой группы, используя grep:
В
-exec
опции{}
стоит имя файла, включая путь. Обратите внимание, что вам не нужно избегать его или ставить в кавычки.Разница между
-exec
терминаторами (+
и\;
) заключается в том,+
что в одну командную строку группируется столько имен файлов, сколько он может. Принимая во внимание,\;
что выполнит команду для каждого имени файла.Итак,
find bands/ -type f -exec grep Drums {} +
приведет к:и
find bands/ -type f -exec grep Drums {} \;
приведет к:В случае
grep
этого имеет побочный эффект либо печать имени файла, либо нет.Конечно,
grep
параметры-h
и-H
будут контролировать, будет ли печататься имя файла независимо от того, какgrep
он называется.xargs
xargs
также может контролировать, как файлы man находятся в командной строке.xargs
по умолчанию группирует все аргументы в одну строку. Для того, чтобы сделать то же самое, что-exec \;
и использоватьxargs -l
. Обратите внимание, что-t
опция указываетxargs
напечатать команду перед ее выполнением.Обратите внимание, что эта
-l
опция указывает xargs выполнять grep для каждого имени файла.По сравнению со значением по умолчанию (то есть без
-l
опции):xargs
имеет лучший контроль над тем, сколько файлов может быть в командной строке. Дайте-l
опцию максимальное количество файлов на команду.Смотрите, что
grep
было выполнено с двумя именами файлов из-за-l2
.источник
Учитывая конкретное название этого поста, вот мое предложение:
Идея состоит в том, чтобы преобразовать пробелы в любой уникальный символ, такой как «<», а затем изменить его на «\», обратную косую черту, за которой следует пробел. Затем вы можете передать это в любую команду, которая вам нравится, например:
Ключ здесь лежит в командах «tr» и «sed»; и вы можете использовать любой символ, кроме «<», например «?» или даже символ табуляции.
источник
tr
? Почему не простоls *.mp3 | sed -n '7!b;s/\([[:space:]]\)/\\\1/g;p'
?Альтернативные решения могут быть полезны ...
Вы также можете добавить нулевой символ в конец ваших строк, используя Perl, а затем использовать
-0
опцию в xargs. В отличие от xargs -d '\ n' (в утвержденном ответе) - это работает везде, включая OS X.Например, для рекурсивного перечисления (выполнения, перемещения и т. Д.) Файлов MPEG3, которые могут содержать пробелы или другие забавные символы - я бы использовал:
(Примечание: для фильтрации я предпочитаю простой для запоминания синтаксис "| grep", а не аргументы "find's" --name.)
источник