Использование разъемов после команды find

Вам нужно будет изменить или изменить тему. Это не контролируется темой metacity, а ваша тема gtk (metacity не имеет ничего общего с панелью объединения).

10
задан 31 October 2017 в 09:37

4 ответа

Вы можете сделать сам find found:

find . -name xac -printf "found\n" -quit

-quit заставит find выйти после первого совпадения, поэтому found печатается не чаще одного раза .

В аналогичной теме на Unix & amp; Linux ( завершает работу после первого совпадения ), я использовал grep -qz, чтобы вернуть ненулевой статус выхода, если find ничего не нашел:

find /some/path -print0 -quit | grep -qz .

Который вы можете использовать для создания составных команд с использованием && или if:

find /some/path -print0 -quit | grep -qz . && echo found
18
ответ дан 22 May 2018 в 16:57
  • 1
    Мне пришлось долго смотреть на это. /some/path сообщает, где начать искать, но ничего не говорит о том, что искать. То же самое в вашем связанном ответе. Что для меня работает find /some/path -name xac -print0 -quit | grep -qz . && echo found. Я что-то пропустил? – Joe 2 November 2017 в 10:18
  • 2
    @Joe, что имеет значение здесь -print0 -quit. То, что вы ставите перед этим, зависит от того, что вы хотите найти. Я решил опустить это здесь. – muru 2 November 2017 в 10:20

Вы можете сделать сам find found:

find . -name xac -printf "found\n" -quit

-quit заставит find выйти после первого совпадения, поэтому found печатается не чаще одного раза .

В аналогичной теме на Unix & amp; Linux ( завершает работу после первого совпадения ), я использовал grep -qz, чтобы вернуть ненулевой статус выхода, если find ничего не нашел:

find /some/path -print0 -quit | grep -qz .

Который вы можете использовать для создания составных команд с использованием && или if:

find /some/path -print0 -quit | grep -qz . && echo found
18
ответ дан 18 July 2018 в 04:13

Ответ muru подходит и хорошо подходит для случаев, когда мы хотим что-то напечатать, если файл найден. Для общего случая, когда мы хотим выполнить внешнюю команду, например echo, мы могли бы использовать флаг -exec.

$ find . -name 'xac' -exec echo "I found " {} \; -quit             
I found  ./xac

Часть {} передает имя файла команде между -exec и \; в качестве аргументов. Обратите внимание на \ перед ; - он не позволяет интерпретировать оболочку из-за неправильной интерпретации, а в закрывающей оболочке точка с запятой означает конец команды, но при экранировании с помощью косой черты оболочка будет рассматривать ее как литерал, который будет передан команде find, и найти команда [

). Для построения условных обозначений if found do this; else do that мы могли бы использовать команду command substition $() и test (aka [):

$ [ "x$(find . -name 'noexist' -print -quit)" != "x" ] && echo "found" || echo "not found"                                                                                              
not found

$ [ "x$(find . -name 'xac' -print -quit)" != "x" ] && echo "found" || echo "not found"                                                                                                  
found

Обращение к комментарию Дана

Дэн в ответ muru спросил:

Не ответил бы «Я нашел {}» лучше, чем эхо «Я нашел» {}? Возможно, для эха все в порядке, но если кто-то копирует команду и заменяет эхо другой командой, у них может быть проблема

. Сначала поймем проблему. Обычно в оболочках существует концепция разделения слов, что означает неупорядоченные переменные, а позиционные параметры будут расширены и рассматриваться как отдельные элементы. Например, если у вас есть переменная var и она содержит текст hello world, когда вы выполняете touch $var, оболочка разбивает ее на два отдельных элемента hello, а world и touch поймут, что, как если бы вы пытались создать 2 отдельных файла; если вы сделаете touch "$var", то оболочка будет обрабатывать hello world как единое целое, а touch создаст только один файл. Важно понимать, что это происходит только из-за того, как работают оболочки.

Напротив, find не страдает от такого поведения, потому что команды обрабатываются самим find и выполняются с помощью execvp(), поэтому нет оболочки. Хотя фигурные скобки имеют особый смысл в оболочках, потому что они появляются в середине команды find, а не в начале, они не имеют особого значения для оболочки в этом случае. Вот пример. Давайте создадим несколько сложных имен файлов и попытаемся передать их в качестве аргумента в команду stat.

$ touch with$'\t'tab.txt with$' 'space.txt with$'\n'newline.txt

$ find -type f -exec stat -c "%F" {} \; -print                                                                                                                         
regular empty file
./with?newline.txt
regular empty file
./with space.txt
regular empty file
./with?tab.txt

Как вы можете видеть, stat получает отличные имена файлов с find, который является одним из основных причин, почему он рекомендуется для использования в переносных сценариях, и особенно полезно, когда вы проходите дерево каталогов и хотите что-то сделать с именами файлов, которые могут иметь в них специальные символы. Поэтому нет необходимости указывать фигурные скобки для команд, выполненных в find.

Это другая история, когда задействована оболочка. Иногда вам нужно использовать оболочку для обработки имени файла. В этом случае цитирование действительно имеет значение, но важно понять, что это не проблема поиска - это оболочка, которая разбивает слово.

$ find -type f -exec bash -c "stat {}" sh \;   
stat: cannot stat './with': No such file or directory
sh: line 1: newline.txt: command not found
stat: cannot stat './with': No such file or directory
stat: cannot stat 'space.txt': No such file or directory
stat: cannot stat './with': No such file or directory
stat: cannot stat 'tab.txt': No such file or directory

Поэтому, когда мы цитируем внутри оболочки, она будет работать. Но опять же, это важно для оболочки, а не find.

$ find -type f -exec bash -c "stat -c '%F' '{}'" sh \;                                                                                                                 
regular empty file
regular empty file
regular empty file
13
ответ дан 22 May 2018 в 16:57
  • 1
    Не лучше ли echo "I found {}", чем echo "I found " {}? Возможно, для эха все в порядке, но если кто-то копирует команду и заменяет эхо другой командой, у них может быть проблема. – Dan 1 November 2017 в 12:58
  • 2
    @ Да, эта тема слишком долго обсуждалась в комментариях, поэтому я сделал редактирование для своего ответа. Пожалуйста, посмотрите – Sergiy Kolodyazhnyy 2 November 2017 в 04:09
  • 3
    Спасибо, наконец, за то, что я понял, почему эта точка с запятой должна быть там. Кроме того, большое объяснение цитирования. – Joe 2 November 2017 в 10:44
  • 4
    Не ожидал так много деталей, как ответ на мой комментарий. Я очень ценю это объяснение, спасибо! – Dan 2 November 2017 в 12:13

Ответ muru подходит и хорошо подходит для случаев, когда мы хотим что-то напечатать, если файл найден. Для общего случая, когда мы хотим выполнить внешнюю команду, например echo, мы могли бы использовать флаг -exec.

$ find . -name 'xac' -exec echo "I found " {} \; -quit I found ./xac

Часть {} передает имя файла команде между -exec и \; в качестве аргументов. Обратите внимание на \ перед ; - он не позволяет интерпретировать оболочку из-за неправильной интерпретации, а в закрывающей оболочке точка с запятой означает конец команды, но при экранировании с помощью косой черты оболочка будет рассматривать ее как литерал, который будет передан команде find, и найти команда [

). Для построения условных обозначений if found do this; else do that мы могли бы использовать команду command substition $() и test (aka [):

$ [ "x$(find . -name 'noexist' -print -quit)" != "x" ] && echo "found" || echo "not found" not found $ [ "x$(find . -name 'xac' -print -quit)" != "x" ] && echo "found" || echo "not found" found

Обращение к комментарию Дана

Дэн в ответ muru спросил:

Не ответил бы «Я нашел {}» лучше, чем эхо «Я нашел» {}? Возможно, для эха все в порядке, но если кто-то копирует команду и заменяет эхо другой командой, у них может быть проблема

. Сначала поймем проблему. Обычно в оболочках существует концепция разделения слов, что означает неупорядоченные переменные, а позиционные параметры будут расширены и рассматриваться как отдельные элементы. Например, если у вас есть переменная var и она содержит текст hello world, когда вы выполняете touch $var, оболочка разбивает ее на два отдельных элемента hello, а world и touch поймут, что, как если бы вы пытались создать 2 отдельных файла; если вы сделаете touch "$var", то оболочка будет обрабатывать hello world как единое целое, а touch создаст только один файл. Важно понимать, что это происходит только из-за того, как работают оболочки.

Напротив, find не страдает от такого поведения, потому что команды обрабатываются самим find и выполняются с помощью execvp(), поэтому нет оболочки. Хотя фигурные скобки имеют особый смысл в оболочках, потому что они появляются в середине команды find, а не в начале, они не имеют особого значения для оболочки в этом случае. Вот пример. Давайте создадим несколько сложных имен файлов и попытаемся передать их в качестве аргумента в команду stat.

$ touch with$'\t'tab.txt with$' 'space.txt with$'\n'newline.txt $ find -type f -exec stat -c "%F" {} \; -print regular empty file ./with?newline.txt regular empty file ./with space.txt regular empty file ./with?tab.txt

Как вы можете видеть, stat получает отличные имена файлов с find, который является одним из основных причин, почему он рекомендуется для использования в переносных сценариях, и особенно полезно, когда вы проходите дерево каталогов и хотите что-то сделать с именами файлов, которые могут иметь в них специальные символы. Поэтому нет необходимости указывать фигурные скобки для команд, выполненных в find.

Это другая история, когда задействована оболочка. Иногда вам нужно использовать оболочку для обработки имени файла. В этом случае цитирование действительно имеет значение, но важно понять, что это не проблема поиска - это оболочка, которая разбивает слово.

$ find -type f -exec bash -c "stat {}" sh \; stat: cannot stat './with': No such file or directory sh: line 1: newline.txt: command not found stat: cannot stat './with': No such file or directory stat: cannot stat 'space.txt': No such file or directory stat: cannot stat './with': No such file or directory stat: cannot stat 'tab.txt': No such file or directory

Поэтому, когда мы цитируем внутри оболочки, она будет работать. Но опять же, это важно для оболочки, а не find.

$ find -type f -exec bash -c "stat -c '%F' '{}'" sh \; regular empty file regular empty file regular empty file
13
ответ дан 18 July 2018 в 04:13

Другие вопросы по тегам:

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