grep: plik wejściowy „X” jest również wynikiem

12

Używam ubuntu 14.4i próbuję przekierować wyjście greppolecenia do pliku, ale ciągle pojawia się ten błąd:

grep: input file 'X' is also the output

Szukałem tego problemu i właśnie dowiedziałem się, że był to błąd, o którym ubuntu 12.4nie ma żadnego opisu. Czy ktoś może mi pomóc w rozwiązaniu tego problemu?

Uruchomię następujące polecenie:

grep -E -r -o -n r"%}(.*){%" > myfile
Kasramvd
źródło
Jeśli próbujesz, grep pattern file > fileto nie działa. Nie można użyć tego samego pliku jako danych wejściowych i wyjściowych dla grep.
jimmij
dodaję moje polecenie! dzięki za podpowiedź, ale kiedy próbuję użyć pliku w innej ścieżce, nie predykuję go i nie mogę tego zrobić!
Kasramvd
na przykład z ../fi weź tobash: ../f.txt: Permission denied
Kasramvd
pokaż pełne polecenie, jaki jest twój plik wejściowy, czy używasz potoku?
jimmij
1
Teraz rozumiem, że rekursywnie przeglądasz całą strukturę katalogów i chcesz dołączyć wynik do pliku, który już istnieje w tej strukturze. Problem polega na tym, że powłoka (bash, zsh, cokolwiek) najpierw wykonuje przekierowania, a dopiero potem wraca do poleceń (w tym przykładzie grep). Oznacza to, że grepw poleceniu grep pattern file > filewidzi już pusty plik, więc nie ma nic jako danych wejściowych. Jednak jeśli użyjesz >>zamiast >tego, plik nie jest pusty, ale grep i tak zgłasza błąd, ponieważ może to prowadzić do cyklicznego przetwarzania tej samej linii (wzorca) w kółko.
jimmij

Odpowiedzi:

9

Nie można użyć tego samego pliku jako wejścia i wyjścia dla grep. Możesz rozważyć następujące alternatywy:

  • plik tymczasowy

    grep pattern file > tmp_file
    mv tmp_file file
    
  • sed

    sed -i -n '/pattern/p' file
  • wstaw cały plik do zmiennej (nie jest to świetny pomysł dla dużych plików)

    x=$(cat file); echo "$x" | grep pattern > file
jimmij
źródło
1
sed może być bardziej przenośnysed -i '/pattern/!d' file
Costas
Ale w przypadku, gdy OP chcesed -i -n 's/.*\(pattern\).*/\1/p' file
Costas
@Czy masz rację, pytanie zostało zredagowane i dodano dodatkowe informacje, aby można było sedrównież dopracować składnię.
jimmij
5

Możesz użyć --excludepola w swoim greppoleceniu w następujący sposób:

grep  --exclude=myfile  -Eron  r"%}(.*){%"  >  myfile
AaronDanielson
źródło
2
Upewnij się, że myfilejest unikalny, ponieważ dotyczy tylko nazwy pliku pliku. Nie chcesz pomijać plików o tej samej nazwie w innych katalogach.
Walf
1

Znalazłem sposób na bash: cat >> IN_OUTPUT_FILE <<< "$(grep something IN_OUTPUT_FILE)"

Polecenie <<<"..."zostanie wykonane jako pierwsze.

osexp2003
źródło