grep: el archivo de entrada 'X' también es la salida

12

Uso ubuntu 14.4e intento redirigir la salida del grepcomando a un archivo, pero sigo recibiendo este error:

grep: input file 'X' is also the output

Busqué este problema y descubrí que se trataba de un error ubuntu 12.4y no hay ninguna descripción, ¿alguien puede ayudarme a resolver este problema?

Ejecuto el siguiente comando:

grep -E -r -o -n r"%}(.*){%" > myfile
Kasramvd
fuente
Si lo estás intentando, grep pattern file > fileentonces no funciona. No puede usar el mismo archivo como entrada y salida para grep.
jimmij
agrego mi comando! gracias por la pista, pero cuando trato de usar un archivo en otra ruta, ¡no lo predica y no puedo hacerlo!
Kasramvd
por ejemplo con ../fi obtener estobash: ../f.txt: Permission denied
Kasramvd
muestre el comando completo, ¿cuál es su archivo de entrada o está utilizando la tubería?
jimmij
1
Ahora entiendo que en realidad está greping recursivamente toda la estructura de directorios y desea agregar el resultado al archivo que ya existe en esta estructura. El problema es que shell (bash, zsh, lo que sea) primero realiza redirecciones y solo luego vuelve a los comandos (grep en este ejemplo). Significa que el grepcomando grep pattern file > fileya ve el archivo vacío, por lo que no tiene nada como entrada. Sin embargo, si usa en >>lugar de >, el archivo no está vacío, pero grep arroja un error de todos modos, ya que puede conducir al procesamiento recursivo de la misma línea (patrón) una y otra vez.
jimmij

Respuestas:

9

No es posible usar el mismo archivo como entrada y salida para grep. Puede considerar las siguientes alternativas:

  • archivo temporal

    grep pattern file > tmp_file
    mv tmp_file file
    
  • sed

    sed -i -n '/pattern/p' file
  • poner todo el archivo en la variable (no es una idea brillante para archivos grandes)

    x=$(cat file); echo "$x" | grep pattern > file
jimmij
fuente
1
sed puede ser más portátilsed -i '/pattern/!d' file
Costas
Pero en el caso que OP quieresed -i -n 's/.*\(pattern\).*/\1/p' file
Costas
@Costas tiene razón, se editó la pregunta y se agregó información adicional para que también se pueda pulir la sedsintaxis.
jimmij
5

Puede usar el --excludecampo en su grepcomando de la siguiente manera:

grep  --exclude=myfile  -Eron  r"%}(.*){%"  >  myfile
AaronDanielson
fuente
2
Asegúrese de que myfilesea ​​único, ya que solo se aplica al nombre base del archivo. No desea omitir archivos con el mismo nombre en otros directorios.
Walf
1

Encontré un camino en bash: cat >> IN_OUTPUT_FILE <<< "$(grep something IN_OUTPUT_FILE)"

El comando <<<"..."se ejecutará primero.

osexp2003
fuente