Как впервые обсуждалось в документации Microsoft для Win32 и различных руководствах программистов Win32 почти четверть века назад, ядро Windows NT не имеет понятия о нескольких дисках, каждый со своими индивидуальными рабочими каталогами. Эта парадигма MS-DOS эмулируется в Win32 с использованием переменных среды, которые обычно не отображаются командами set
интерпретаторов команд Win32 (но довольно легко доступны программно) с именами в форме ] = D :
(где D
- буква диска). Эта претензия на несколько рабочих каталогов, как и старый добрый MS-DOS, является общей фикцией, которую консультируют и поддерживают Win32 API, командный интерпретатор Microsoft cmd
и библиотеки времени выполнения для различных языков, включая некоторые C и C ++. компиляторы.
Когда процесс Cygwin запускается, он преобразует блок среды Win32 в "более UNIX-y" форму. В нем есть целый набор зашитых специальных правил преобразования для различных конкретных переменных, таких как PATH
. Этого нет в документации Cygwin, но он также имеет дело со строками окружения = D : = D : \ path
путем преобразования ведущих =
в !
. Это дает строки окружения, как их видит выполнение программы Cygwin, вида ! D : = D : \ путь
.Он отменяет это преобразование, когда ему необходимо создать новую среду Win32 по какой-либо причине, например, порождение нового процесса, включение !
обратно в =
.
Чтобы командный интерпретатор Microsoft отображал эти переменные среды, нужно просто запустить
set "", после чего можно будет увидеть вывод, начинающийся примерно с
=C:=C:\Users\Jim …
. Иногда появляется дополнительная одна из этих переменных среды с :
] в качестве буквы диска. Выполнение той же команды set
, как указано выше, дает начало вывода
=::=::\ =C:=C:\Users\Jim …
После того, как Cygwin сделал "больше UNIX-y", это, конечно же, тот самый ! :: = :: \
, что вы видите.
Поскольку это механизм, который встроен в приложения Win32 (особенно в командный интерпретатор Microsoft) и частично связан с самим Win32 API, предотвратить их существование не так просто.
CreateProcess ()
». Справочник программиста Microsoft Win32: функции, A – G . Microsoft Press. 1993. ISBN 9781556155178. стр. 213. Вот неправильный ответ.
awk 'NR == 1 || NR == 10 || NR == 100 {gsub(/old/,"new")}; {print}' <file name>
NR == 1 || NR == 10 || NR == 100
:выполните следующие команды только в одной из этих строк. gsub(/old/,"new")
:замените /old/
на new
. {print}
:независимо от того, на какой строке вы находитесь, напечатайте строку. А как насчет:
sed -e '
/something_identifying_startline/,/something_identifying_endline/{
s/dog/cat/
s/black/white/
}
Насколько мне известно, sed-адреса могут состоять только из одной строки или диапазона строк.
Однако вы можете собрать что-то вместе, используя sed -f -
для чтения команд из стандартного ввода вместе с вашей оболочкой. Например:
printf '%ds/<old string>/<new string>/g\n' {1,10,100} | sed -f - file
Альтернатива напрямую с sed:
sed '1b1; 10b1; 100b1; b ;:1;s/<old string>/<new string>/g' <file name>
Если номер строки соответствует 1, 10 или 100, перейти к метке 1; в других строках просто переходите к концу (, который по умолчанию печатает строку ).
несколько автоматизированный:
sed -e $(printf '%sb1;' 1 10 100) -e 'b; :1;s/<old>/<new>/g' <file name>
POSIXly (с IFS по умолчанию):
sed $(printf -- '-e %sb1 ' 1 10 100) -e 'b' -e':1' -e 's/<old>/<new>/g'