Почему 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 

  • Замените все вхождения \ except \ N
  • Как удалить определенные символы (но не все) перед одним или несколькими символами?
  • Как получить только определенные поля из данного файла?
  • Как заменить пользовательскую строку даты в текстовом файле
  • Должен быть лучший способ заменить одиночные новые строки?
  • Застрял в разделении символов на строки в моем подходе. Нашел рабочий подход, но не может его понять
  • sed или awk: удалить строку, которая начинается с числа и заканчивается на rpm
  • Добавьте 0, когда значение равно 12 символам
  • 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 сохранить и закрыть

    Interesting Posts

    Почему этот скрипт не работал?

    Как смонтировать образ BlindWrite B6T / B6I на Debian Jessie?

    Как создать локального пользователя в Linux-системах с поддержкой LDAP

    Сохраняйте количество ресурсов для виртуальной консоли (Ctrl + Alt + Fx)

    Как заполнить 90% свободной памяти?

    Каталог Untar из большого tarball

    Почему я получаю сообщение «Не могу вернуться в безопасный режим» всякий раз, когда я пытаюсь запустить игру?

    Заблокировать скрипт, запускающий демоны

    Как получить качественное шифрование на диске Debian после установки?

    Получение комбинированного подсчета всех вхождений строки в несколько каталогов?

    IRSSI: отключить звонок на активность в определенном канале

    x86 Emulator для Linux с подробной отладкой

    Как использовать / etc / fbtab в OpenBSD для обеспечения безопасности X11?

    Попытка проверить целостность файла с помощью GnuPG. «ПЛОХАЯ подпись» все время

    При попытке открыть / dev / mtd2 для доступа для чтения / записи: разрешение отклонено

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