grep: le fichier d'entrée «X» est également la sortie

12

J'utilise ubuntu 14.4et tente de rediriger la sortie de la grepcommande vers un fichier, mais je reçois toujours cette erreur:

grep: input file 'X' is also the output

J'ai recherché ce problème et je viens de découvrir qu'il s'agissait d'un bogue ubuntu 12.4et qu'il n'y a pas de description, quelqu'un peut-il m'aider à résoudre ce problème?

J'exécute la commande suivante:

grep -E -r -o -n r"%}(.*){%" > myfile
Kasramvd
la source
Si vous essayez, grep pattern file > filecela ne fonctionne pas. Vous ne pouvez pas utiliser le même fichier comme entrée et sortie pour grep.
jimmij
j'ajoute ma commande! merci pour l'astuce, mais quand j'essaie d'utiliser un fichier dans un autre chemin, il ne le prédicat pas et je ne peux pas le faire!
Kasramvd
par exemple avec ../fi obtenez cecibash: ../f.txt: Permission denied
Kasramvd
show full command, quel est votre fichier d'entrée, ou utilisez-vous le tuyau?
jimmij
1
Maintenant, je comprends que vous grepez récursivement toute la structure de répertoires et que vous souhaitez ajouter le résultat au fichier qui existe déjà dans cette structure. Le problème est que le shell (bash, zsh, peu importe) effectue d' abord des redirections et revient ensuite aux commandes (grep dans cet exemple). Cela signifie que grepdans la commande grep pattern file > filevoit un fichier déjà vide, n'a donc rien en entrée. Cependant, si vous utilisez à la >>place de >alors le fichier n'est pas vide, mais grep renvoie de toute façon une erreur car cela peut conduire à un traitement récursif de la même ligne (modèle) encore et encore.
jimmij

Réponses:

9

Il n'est pas possible d'utiliser le même fichier en entrée et en sortie pour grep. Vous pouvez envisager les alternatives suivantes:

  • Fichier temporaire

    grep pattern file > tmp_file
    mv tmp_file file
    
  • sed

    sed -i -n '/pattern/p' file
  • mettre tout le fichier dans la variable (idée pas brillante pour les gros fichiers)

    x=$(cat file); echo "$x" | grep pattern > file
jimmij
la source
1
sed peut être plus portablesed -i '/pattern/!d' file
Costas
Mais dans le cas où OP veutsed -i -n 's/.*\(pattern\).*/\1/p' file
Costas
@Costas vous avez raison, la question a été modifiée et des informations supplémentaires ont été ajoutées afin que l'on puisse également peaufiner la sedsyntaxe.
jimmij
5

Vous pouvez utiliser le --excludechamp dans votre grepcommande comme ceci:

grep  --exclude=myfile  -Eron  r"%}(.*){%"  >  myfile
AaronDanielson
la source
2
Assurez-vous qu'il myfileest unique car il ne s'applique qu'au nom de base du fichier. Vous ne voulez pas ignorer les fichiers portant le même nom dans d'autres répertoires.
Walf
1

J'ai trouvé un moyen de bash: cat >> IN_OUTPUT_FILE <<< "$(grep something IN_OUTPUT_FILE)"

La commande dans <<<"..."sera exécutée en premier.

osexp2003
la source