Подтвердить что ты не робот

Использовать команду команд в качестве аргумента для diff

У меня возникают проблемы с этой простой задачей:

cat file | grep -E ^[0-9]+$ > file_grep
diff file file_grep

Проблема в том, что я хочу сделать это без file_grep

Я пробовал:

diff file `cat file | grep -E ^[0-9]+$`

и

diff file "`cat file | grep -E ^[0-9]+$`"

и несколько других комбинаций:-), но я не могу заставить его работать. Я всегда получаю сообщение об ошибке, когда diff получает дополнительный аргумент, который является содержимым файла, отфильтрованного grep.

Что-то подобное всегда срабатывало для меня, когда я хотел echo выводить команды из script как это (используя escape-обратные экраны):

echo `ls`

Спасибо

4b9b3361

Ответ 1

Если вы используете bash:

diff file <(grep -E '^[0-9]+$') file

Последовательность <(COMMAND) расширяется до имени псевдофайла (например, /dev/fd/63), из которого вы можете прочитать вывод команды.

Но для этого конкретного случая решение руаха проще. Он использует тот факт, что - как аргумент diff заставляет его читать стандартный ввод. Синтаксис <(COMMAND) становится более полезным, когда оба аргумента diff являются выходными данными команды, такими как:

diff <(this_command) <(that_command)

Ответ 2

Самый простой способ:

grep -E '^[0-9]+$' file | diff file -

Дефис - в качестве имени файла представляет собой конкретную нотацию, которая сообщает diff "использовать стандартный ввод"; он задокументирован в man-странице diff. (Большинство общих утилит поддерживают одну и ту же нотацию.)

Причина, по которой backticks не работает, заключается в том, что они захватывают вывод команды и передают ее в качестве аргумента. Например, это:

cat `echo file`

эквивалентно этому:

cat file

и это:

diff file "`cat file | grep -E ^[0-9]+$`"

эквивалентно примерно так:

diff file "123
234
456"

То есть, он фактически пытается передать 123234345 (плюс новые строки) как имя файла, а не как содержимое файла. Технически вы могли бы достичь последнего, используя функцию Bash "замещение процесса", которая фактически создает своего рода временный файл:

diff file <(cat file | grep -E '^[0-9]+$')

но в вашем случае это не нужно, из-за diff поддержки -.

Ответ 3

grep -E '^[0-9]+$' file | diff - file

где - означает "читать со стандартного ввода".

Ответ 4

Попробуйте заменить процесс:

$ diff file <(grep -E "^[0-9]+$" file)

Из bash manpage:

Замена процесса

Подстановка процесса поддерживается в системах, которые поддерживают именованные каналы (FIFO) или метод /dev/fd    Именование открытых файлов. Он принимает форму < (list) или > (list). Список процессов запускается со своим вводом или    вывода, подключенного к FIFO или некоторому файлу в /dev/fd. Имя этого файла передается как аргумент    текущая команда в результате расширения. Если используется формa > (список), запись в файл    предоставит вход для списка. Если используется форма < (list), файл, переданный как аргумент, должен быть прочитан    для получения вывода списка.

Ответ 5

В bash синтаксис

diff file <(cat file | grep -E ^[0-9]+$)