grep: входной файл 'X' также является выходным

12

Я использую ubuntu 14.4и пытаюсь перенаправить вывод grepкоманды в файл, но продолжаю получать эту ошибку:

grep: input file 'X' is also the output

Я искал эту проблему и только что обнаружил, что это ошибка, ubuntu 12.4и нет никакого описания, может кто-нибудь помочь мне разобраться в этой проблеме?

Я запускаю следующую команду:

grep -E -r -o -n r"%}(.*){%" > myfile
Kasramvd
источник
Если вы пытаетесь, grep pattern file > fileто это не сработает. Вы не можете использовать тот же файл, что и для ввода и вывода для grep.
Джимми
я добавляю свою команду! спасибо за подсказку, но когда я пытаюсь использовать файл по другому пути, он не предопределяет его, и я не могу этого сделать!
Kasramvd
например с ../fi получить этоbash: ../f.txt: Permission denied
Kasramvd
Команда show full, какой у вас входной файл или вы используете канал?
Джимми
1
Теперь я понимаю, что вы на самом деле рекурсивно извлекаете всю структуру каталогов и хотите добавить результат в файл, который уже существует в этой структуре. Проблема в том, что оболочка (bash, zsh и т. Д.) Сначала выполняет перенаправление, а затем возвращается к командам (в этом примере grep). Это означает, что grepв команде grep pattern file > fileвидит уже пустой файл, поэтому ничего не имеет в качестве ввода. Однако, если вы используете >>вместо >этого файл не пустой, но grep выдает ошибку в любом случае, так как это может привести к рекурсивной обработке одной и той же строки (шаблона) снова и снова.
Джимми

Ответы:

9

Невозможно использовать тот же файл, что и для ввода и вывода grep. Вы можете рассмотреть следующие варианты:

  • временный файл

    grep pattern file > tmp_file
    mv tmp_file file
  • СЭД

    sed -i -n '/pattern/p' file
  • поместите весь файл в переменную (не очень хорошая идея для больших файлов)

    x=$(cat file); echo "$x" | grep pattern > file
jimmij
источник
1
Сед может быть более портативнымsed -i '/pattern/!d' file
Костас
Но в случае, если ОП хочетsed -i -n 's/.*\(pattern\).*/\1/p' file
Костас
@ Так как вы правы, вопрос был отредактирован и добавлена ​​дополнительная информация, чтобы можно было также улучшить sedсинтаксис.
Джимми
5

Вы можете использовать --excludeполе в вашей grepкоманде следующим образом:

grep  --exclude=myfile  -Eron  r"%}(.*){%"  >  myfile
AaronDanielson
источник
2
Убедитесь, что myfileон уникален, так как он применяется только к базовому имени файла. Вы не хотите пропускать файлы с тем же именем в других каталогах.
Walf
1

Я нашел способ в Bash: cat >> IN_OUTPUT_FILE <<< "$(grep something IN_OUTPUT_FILE)"

Команда в <<<"..."будет выполнена первой.

osexp2003
источник