Вариант А лучше, даже если вы его сейчас не видите.
Хранение нескольких значений в одной «ячейке» базы данных является ошибкой при любом взгляде на нее (хотя, к сожалению, это очень распространенная ошибка), не говоря уже о том, что это нарушение первой нормальной формы , в которой конкретно говорится что каждый столбец может содержать только одно атомарное значение в каждой строке (хотя исходное правило использует другую терминологию).
Недостатки многочисленны, и некоторые из них являются критическими, в том числе (но не ограничиваясь ими):
Список можно продолжать и продолжать - но я думаю, что каждый должен получить картину сейчас - столбец базы данных следует использовать для хранения одного значения для каждой строки - каждый раз.
Подключение по конвейеру к другому процессу (хотя это НЕ выполнит того, что вы сказали, что пытаетесь сделать):
command1 | command2
Это отправит вывод команды 1 в качестве входных данных команды 2
-exec
на find
(это будет делать то, что вы хотите, но только для ] найти
)
найти. -name '* .foo' -exec cat {} \;
(Все между find
и -exec
- это предикаты поиска, которые вы уже использовали. {}
заменит конкретный файл, который вы нашли, в команду ( cat {}
в данном случае); \;
означает завершение команды -exec
.)
отправить вывод одного процесса в качестве аргументов командной строки другому процессу
command2 `command1`
например:
cat` find. -name '* .foo' -print`
(Обратите внимание, что это ОБРАТНЫЕ ЦИТАТЫ, а не обычные кавычки (под тильдой ~ на моей клавиатуре).)
Это отправит вывод command1
в command2
в качестве аргументов командной строки. Обратите внимание, что имена файлов, содержащие пробелы (новые строки и т. Д.), Будут разбиты на отдельные аргументы.
Вы пытаетесь найти текст в файлах? Вы можете просто использовать для этого grep ...
grep searchterm *
Sounds like a job for a shell script to me:
for file in 'find -name *.xml'
do
grep 'hello' file
done
or something like that
Есть несколько способов передать список файлов, возвращаемый командой find
, команде cat
, хотя технически не все используйте piping, и ни один из них на самом деле не передает напрямую к cat
.
Самый простой - использовать обратные кавычки ( `
):
При этом вывод find
эффективно помещается в командную строку cat
. Это не сработает, если find
имеет слишком много вывода (больше, чем может поместиться в командной строке) или если вывод содержит специальные символы (например, пробелы).
В некоторых оболочках, включая bash
, можно использовать $ ()
вместо обратных кавычек:
cat $ (найти [что угодно])
Это менее портативный, но вмещаемый. Помимо этого, он имеет почти те же предостережения, что и обратные кавычки.
Поскольку выполнение других команд над тем, что было найдено, является обычным использованием для find
, find имеет действие -exec
который выполняет команду для каждого найденного файла:
find [something] -exec cat {} \;
{}
- это заполнитель для имени файла, а \;
обозначает конец команды (после -exec
возможны другие действия ].)
Это запустит cat
один раз для каждого отдельного файла, вместо того, чтобы запускать один экземпляр cat
, передавая ему несколько имен файлов, что может быть неэффективным и может не иметь такого поведения, как вы нужны некоторые команды (хотя это нормально для cat
). Синтаксис также неудобен для ввода - вам нужно избегать точки с запятой, потому что точка с запятой является особенной для оболочки!
Некоторые версии find
(особенно версия GNU) позволяют вам заменить ;
с +
, чтобы использовать режим добавления -exec
для запуска меньшего количества экземпляров cat
:
Это передаст несколько имен файлов при каждом вызове cat
, что может быть более эффективным.
Обратите внимание, что не гарантированно использует один вызов, однако. Если командная строка будет слишком длинной, аргументы будут распределены между несколькими вызовами cat
. Для cat
это, вероятно, не имеет большого значения, но для некоторых других команд это может изменить поведение нежелательным образом. В системах Linux ограничение длины командной строки довольно велико, поэтому разделение на несколько вызовов довольно редко по сравнению с некоторыми другими ОС.
Классический / переносимый подход заключается в использовании xargs
:
find [что угодно] | xargs кошка
xargs
выполняет указанную команду (в данном случае cat
) и добавляет аргументы в зависимости от того, что она читает из стандартного ввода. Так же, как -exec
с +
, при необходимости командная строка прерывается. То есть, если find
выдаст слишком много результатов, он будет запускать cat
несколько раз. Как упоминалось ранее в разделе о -exec
, есть некоторые команды, в которых такое разбиение может привести к другому поведению. Обратите внимание, что при использовании xargs
подобным образом возникают проблемы с пробелами в именах файлов, поскольку xargs
просто использует пробелы в качестве разделителя.
Самый надежный, переносимый и эффективный метод также использует ] xargs
:
найти [что угодно] -print0 | xargs -0 кот
Флаг -print0
указывает find
использовать разделители \ 0
(нулевой символ) между именами файлов и флаг -0
сообщает xargs
ожидать этих разделителей \ 0
. Его поведение практически идентично подходу -exec
... +
, хотя он более переносимый (но, к сожалению, более подробный).
POSIX 2008 добавила маркер +
в find
, что означает, что теперь он автоматически группирует столько файлов, сколько разумно, для выполнения одной команды, очень похоже на xargs
, но с рядом преимуществ:
Проблема с именем файла - это проблема с xargs
без параметра -0
, а проблема «запускать даже с нулевым именем файла» - это проблема с или без параметр -0
, но GNU xargs
имеет параметр -r
или - no-run-if-empty
, чтобы предотвратить это происходит. Кроме того, это обозначение сокращает количество процессов, не то чтобы вы могли измерить разницу в производительности. Следовательно, вы могли бы разумно написать:
find . -exec grep something {} +
find . -print | xargs grep something
Если вы работаете в Linux или у вас есть команды GNU find
и xargs
, тогда используйте -print0
с find
и -0
с xargs
для обработки имен файлов, содержащих пробелы и другие нечетные символы.
find . -print0 | xargs -0 grep something
grep
Если вам не нужны имена файлов (только текст), добавьте соответствующий параметр в grep
(обычно -h
для подавления «заголовков»). Чтобы абсолютно гарантировать, что имя файла печатается grep
(даже если найден только один файл или при последнем вызове grep
дается только 1 имя файла),
The find command has an -exec argument that you can use for things like this, you could just do the grep directly using that.
For example (from here, other good examples at this page):
find . -exec grep "www.athabasca" '{}' \; -print
Чтобы вывести список и просмотреть содержимое всех файлов abc.def на сервере в каталогах / ghi и / jkl
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec ls {} \; -exec cat {} \;
Чтобы вывести список файлов abc.def с комментариями и отображением, просмотрите эти записи в каталогах / ghi и / jkl
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec grep -H ^# {} \;