Учитывая тег vi
в этом вопросе и тот факт, что я обнаружил, что автоматическое редактирование файлов с помощью POSIX-совместимого ex
командам на этом сайте уделяется меньше внимания по сравнению с множеством советов по sed
, awk
, grep
и даже Perl, вот POSIX-совместимая команда ex
, которая будет выполнять желаемую фильтрацию:
ex -sc 'g/.*\(on line\)/s//\1/ | .w!>>output
q!' input
Обратите внимание на встроенную новую строку в команде - это необходимо для полной переносимости POSIX, поскольку нет другого определенного способа завершить g
лобальная команда; однако большинство реализаций допускают несколько команд -c
, и в этом случае следующий один лайнер будет работать точно так же:
ex -sc 'g/.*\(on line\)/s//\1/ | .w!>>output' -c 'q!' input
Есть немного магии регулярных выражений и много ex
-командная магия, содержащаяся в этой команде, и, поскольку ex
, похоже, не очень широко известен, я объясню каждую часть:
-s
начинается ex
в автоматическом режиме, «при подготовке к пакетной обработке», поэтому на ваш терминал ничего не выводится.
-c
означает «Выполнить следующую команду при открытии файла». ( input
- это имя файла, который нужно открыть.)
Сама по себе команда ex
представляет собой две команды:
g/.*\(on line\)/s//\1/ | .w!>>output
q!
g
- это «глобальная» команда и означает: «Выполнить следующие команды (оставшуюся часть строки) во всех строках файла, соответствующих указанному регулярному выражению».
Заданное регулярное выражение - .* \ (в строке \)
, что означает «Любые символы любое количество раз, включая 0, за которым следует« в строке »». Круглые скобки используются для записи «онлайн» для последующего обратного обращения.
На самом деле сама команда g
могла бы быть с таким же успехом g / on line /
, и она работала бы так же. Однако написанная мной команда s
ubstitute использует ничего для своего регулярного выражения - s //
- что означает «повторно использовать последнее использованное регулярное выражение». Затем команда s
использует \ 1
для текста замены, что в данном случае означает «онлайн».
Символ канала |
в команде ex
не означает канал, как в оболочке. Вместо этого он обычно используется для разделения отдельных команд ex
, каждая из которых должна выполняться последовательно, но независимо. Однако команда lobal g
является исключением: в глобальной команде вертикальная черта разделяет команды, которые все являются внутри глобальной команды, то есть такие команды выполняются только в строках, соответствующих регулярному выражению , указанному в глобальной команде.
Команда, следующая за вертикальной чертой, в данном случае является командой обряда w
. Ему предшествует точка .
с указанием «текущей строки»; без этого спецификатора адреса команда записи запишет весь файл, независимо от текущей строки.(Поскольку мы используем команду записи в глобальной команде, если бы мы опускали точку, команда записи записывала бы весь файл после , в каждой соответствующей строке выполнялась команда подстановки!)
>>
означает: «Если файл уже существует, добавить к нему, а не выдавать ошибку». Поскольку мы записываем в файл несколько раз, это необходимо, иначе мы получим только последнюю строку, которая была записана в выходной файл. !
перед >>
означает «Если файл не уже существует, создайте файл и запишите в него, а не выдает ошибку». (Без !
в POSIX не указано, произойдет это или нет.) И, конечно же, output
- это имя файла для записи.
Наконец, конечно, q!
означает «выйти без сохранения изменений в текущем файле». Мы произвели замены во многих строках входного файла
, но мы не хотим сохранять эти изменения, поэтому используем q!
.
Есть несколько других подходов, которые эквивалентны, например следующий:
ex -sc '%s/.*\(on line\)/\1/e | v//d
w output | q!' input
Но здесь используется флаг e
для команды замены, которой нет в POSIX. (Если этот флаг опущен, пакетная обработка будет остановлена в том случае, если регулярное выражение . * \ (On line \)
не найдено нигде в файле.)
Конечно, где ex
действительно сияет в редактировании файла на месте . Но его, безусловно, можно использовать для фильтрации файла в другой файл, как показано выше.
Ответ:
Когда вы открываете символическую ссылку на файл, вы точно открываете символическую ссылку, читаете текст в символической ссылке (из ссылки ), закрываете ее и открываете файл, на который она ссылается. Так что это означает, когда вы его редактируете. Вы никогда не редактировали файл символической ссылки.
Каталог содержит другие каталоги или указатели на файл:
Это данные в начале диска.
A 16:44:
-- B 17:18:
-- C 3kb: 15754
-- D 4kb: 26544
-- E 18:10:
-- F 6kb: 16754
-- G 8kb: 27544
При редактировании файла в КАТАЛОГЕ. изменен размер файла, изменена дата (и другие атрибуты ). И это изменено в информации каталога. Итак, вы также редактировали данные каталога (, размер, дату... ). Итак, каталог изменен.
Результат:
Это данные о начале диска после редактирования C.
A 18:20:
-- B 18:20:
-- C 8kb: 15754
-- D 4kb: 26544
-- E 18:10:
-- F 6kb: 16754
-- G 8kb: 27544
Поскольку, когда вы просите отредактировать b.txt
, вы редактируете a.txt
, ссылка остается неизменной. :Переход по ссылке не меняет ее.
Попытка получить доступ к ссылке приводит к доступу к файлу, на который она указывает (или к конечному файлу, на который указывает ссылка, ссылка может указывать на ссылку, которая указывает на ссылку, которая в конечном итоге указывает на файл/каталог/что-то -иначе ). Ссылки доступны только с использованием специальных процедур доступа к ссылкам. Кроме того, программные -ссылки нельзя редактировать (, только создавать и удалять ).