Почему sed действует по-разному в зависимости от выходного файла?

Если я запустил:

cat messages.txt | sed -e 's/a/a/g' > messages.txt 

на один большой файл (2500+ строк) Я обнаружил, что в результате получится только около 900 строк после команды в cygwin и не будет никаких строк в gentoo. Однако, если я запускаю

 cat messages.txt | sed -e 's/a/a/g' > other_messages.txt 

он сохраняет все строки, как следует.

Мой вопрос в том, почему и есть ли способ сделать это иначе, чем

 cat messages.txt | sed -e 's/a/a/g' > other_messages.txt rm messages.txt mv other_messages.txt messages.txt 

4 Solutions collect form web for “Почему sed действует по-разному в зависимости от выходного файла?”

Почему бы вам просто не написать

 sed -i -e 's/a/a/g' messages.txt 

-i означает «на месте»,

Ответ fschmitt является лучшим при использовании sed; однако в более общем смысле этот анти-шаблон:

 cat infile | filter > infile 

вероятно, вызовет у вас множество проблем. Например, если у меня есть файл с именем infile который выглядит так:

 Hello World 

и запустите эту команду:

 cat infile | tr "[:upper:]" "[:lower:]" 

я получил

 hello world 

Но если я запустил cat infile | tr "[:upper:]" "[:lower:]" > infile cat infile | tr "[:upper:]" "[:lower:]" > infile Я получу пустой файл. Зачем?

Ну, когда вы используете оператор перенаправления вывода > вы говорите: «Поместите мой стандартный вывод в этот файл, и если этот файл существует, перепишите его». Теперь вы можете подумать, что это должно сработать, так как ваш фильтр вернет все строки исходного файла. Однако то, что часто заканчивается, заключается в том, что оболочка будет сжимать ваш файл до того, как будут прочитаны строки. Затем ваша команда фильтра перейдет к чтению строк из пустого файла, не найдет ни одного и, следовательно, не вернет ни одного. В некоторых местах вам может быть достаточно «повезло», чтобы некоторые строки были прочитаны до того, как файл обрушится, но лучше всего просто избегать этого шаблона.

Чтобы обойти эту проблему, у вас есть несколько вариантов. Один из них заключается в том, чтобы просто сделать что-то вроде:

 cat infile | filter > tmpfile; mv tmpfile infile 

Если вам нужно быть уверенным, что ваш временный файл не будет сжимать какой-либо другой файл или другие неприятные вещи произойдут с ним, вы должны посмотреть в mktemp . (см. man mktemp и info coreutils mktemp )

Другой вариант – использовать sponge из moreutils .

Кроме того, многие из этих примеров являются примерами бесполезных применений cat .

Еще один (переносимый) способ редактирования файла на месте – использовать ed .

 # cf. http://wiki.bash-hackers.org/howto/edit-ed cat <<-'EOF' | ed -s messages.txt H ,g/a/s//b/g wq EOF # ... or read the file contents into a variable, modify it and write it back to file file_contents="$(cat messages.txt)" printf '%s' "$file_contents" | sed -e 's/a/b/g' > messages.txt # ... and, if you want to play around with a file descriptor hack, ... # (As long as there's a fd associated with a file, the file can be accessed via the fd.) exec 3<messages.txt # open file on fd 3 for reading rm -f messages.txt sed -e 's/a/b/g' <&3 > messages.txt 

Вы можете использовать Vim в режиме Ex:

 ex -sc '%s/OLD/NEW/g|x' messages.txt 
  1. % выбрать все строки

  2. s заменить

  3. Глобальная замена

  4. x сохранить и закрыть

  • эталонная проблема при использовании sed
  • Как заменить строку в файле другим файлом?
  • Какие команды вы можете использовать в начале команды sed?
  • Удалите первый и последний символы, если они есть
  • Sed целое слово с заменой отдельных букв, с BSD sed?
  • Удалите первые n строк из файла с переменной
  • Заменить кратчайшее совпадение строкового рисунка
  • Как заменить запятые на пробелы в csv, но вставляя другое количество пробелов после каждого столбца?
  • Печать 2-й и 7-й строк в файл с помощью `sed`
  • Хотите напечатать формат таблицы с несколькими строками в командной строке
  • Sed заменить алфавит на верхний регистр после периода
  • Interesting Posts

    где находятся файлы .buildinfo, хранящиеся в пакете debian source?

    Как создать структурированный список всех файлов и каталогов в определенном каталоге (рекурсивно)?

    Убивать детские задания, длительностью более 20 минут

    Можно ли использовать драйвер nvidia только в играх и нуво в любое другое время?

    X-сервер, запущенный kdm, умирает во время запуска из-за невозможности загрузки ключевой карты

    Вывод общих строк из 2-х файлов и необычных строк из обоих файлов в один выходной файл

    Как завершить вывод команды watch?

    Включить параметры удаленной печати с помощью cups-lpd

    Почему sed не удаляет мои пустые строки?

    создать псевдо-оболочку для команды

    Почему существует * Когда упоминается Unix по всему Интернету?

    Концепция отображения памяти в Unix-подобных системах

    Каков самый быстрый способ запуска скрипта?

    Как установить PostgreSQL 9.3 в тюрьму FreeBSD?

    Как использовать аргументы имени файла или по умолчанию для stdin, stdout (краткое)

    Linux и Unix - лучшая ОС в мире.