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

В то время как открытость является, конечно, частью его, я думаю, что ключевой фактор является длительной настойчивостью Linus Torvald, что вся работа, от большого до маленького, имеет место в магистрали ядро Linux, пока она хорошо сделана. Если он решил в какой-то момент чертить линию и сказать "хорошо для того необычного суперкомпьютерного оборудования, нам нужно ветвление", затем абсолютно отдельный высокопроизводительный и варианты маленькой системы, возможно, разработал. Как это, вместо этого люди сделали более трудную работу того, чтобы заставлять все это играть вместе относительно хорошо.

И, клуджам, которые включают одну сторону вещей во вреде другого, обычно, не позволяют войти — снова, вынуждая людей решить проблемы более твердым, но более корректным способом, который, оказывается, обычно легче продвинуться от однажды, независимо от того, что требуется, клудж становится исторической сноской.

Из интервью несколько лет назад:

Q: Linux является универсальной системой. Это предоставляет ПК, огромные серверы, мобильные телефоны и приблизительно десять из других устройств. От Вашего привилегированного положения, какой сектор будет тем, где Linux выразит самый высокий потенциал?

A: Я думаю, что действительная мощность Linux состоит точно в том, что это не об одной нише. Все добираются для манипулирования, и у различных людей и различных компаний есть полностью различные мотивации и верования в то, что важно для них. Таким образом, я даже не интересуюсь никаким конкретным сектором.

5
10.11.2011, 11:19
4 ответа

Почему Вы просто не пишете

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

-i означает "на месте"

10
27.01.2020, 20:31
  • 1
    , Предупреждающий: не все варианты sed реализуйте эту опцию. –  mouviciel 06.10.2010, 16:50

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

cat infile | filter > infile

вероятно, вызовет Вас большое количество проблем. Например, если мне назвали файл infile это похоже на это:

Hello
World

и выполненный эта команда:

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

Я добираюсь

hello
world

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

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

Для обхождения этой конкретной проблемы, у Вас есть несколько опций. Нужно просто сделать что-то как:

cat infile | filter > tmpfile; mv tmpfile infile

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

Другая опция состоит в том, чтобы использовать sponge от moreutils.

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

11
27.01.2020, 20:31

Еще один (портативный) способ отредактировать оперативный файл состоит в том, чтобы использовать 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
2
27.01.2020, 20:31

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

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

  2. s заменить

  3. g глобальную замену

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

0
27.01.2020, 20:31

Теги

Похожие вопросы