Попробуйте / sbin / nologin
в / etc / passwd
, пользователь может выполнить.
На самом деле имеется дваw
элемента. Один — команда, другой — флаг s///
.
Оба используются для записи текущего пространства шаблонов в файл.
Например, эта команда w
запишет вoutfile
(сделать копию):
$ printf '%s\n' AA BB CC DD EE > infile
$ sed -n 'w outfile' infile
$ cat outfile
AA
BB
CC
DD
EE
Опция -n
позволяет избежать печати любого пространства шаблона, но команда w
будет write
каждый шаблон (строку )указывать на имя файла в аргументе после команды w
(, которая должна завершить команду ).
Это, вместо этого, напишет только одну строку (строку, которая имеет (по крайней мере )одинC
):
$ sed -n '/C/ w outfile' infile ; cat outfile
CC
Другой элемент w
— это флаг w
для команды s///
, который хотя и означает примерно то же самое write
, но выполняется только в том случае, если подстановка в команде s///
была выполнена:
$ sed -n 's/C/X/w outfile' infile; cat outfile
XC
But where do I put the w substitution flag if I'm using multiple commands and want the results wrote to a file?
Поскольку флаг подстановки связан с одной (конкретной )заменой, где его следует использовать, зависит от того, какую замену необходимо записать:
$ sed -n -e 's/B/X/w outfile' -e 's/D/Y/' infile; cat outfile
XB
Обратите внимание, что каждая замена должна быть в отдельной-e
(или отдельной строке ), так как имя выходного файла должно заканчиваться командой (требуется новая строка ),или может быть записано как:
$ sed -n -e 's/B/X/w outfile
> s/D/Y/' infile; cat outfile
XB
Другая замена может быть выбрана с помощью:
$ sed -n -e 's/B/X/' -e 's/D/Y/w outfile' infile; cat outfile
YD
Или оба:
$ sed -n -e 's/B/X/w outfile' -e 's/D/Y/w outfile' infile; cat outfile
XB
YD
Или используйте команду w
(без флага)(и предполагая, что GNU sed):
$ sed -n 's/B/X/;s/D/Y/;w outfile' infile; cat outfile
AA
XB
CC
YD
EE
I want to write the whole output to the file, a copy of the original with the changes made.
Флаг подстановки не может записать весь файл, если замена не происходит для всех строк. Вам нужно использовать команду w
(, предполагая, что bash):
$ printf 'The quick brown fox jumps over the lazy dog%.0s\n' {1..14} >catAndDog.txt
$ sed -n '4 { s/fox/elephant/ ; s/dog/cat/ } ; w outfile' catAndDog.txt
$ cat outfile
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown elephant jumps over the lazy cat
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
Поймите, что флаг w
для каждой замены будет печатать строку для каждой замены, так что это произойдет:
$ sed -n -e '4 { s/fox/elephant/w outfile' -e 's/dog/cat/w outfile' -e '}' catAndDog.txt
$ cat outfile
The quick brown elephant jumps over the lazy dog
The quick brown elephant jumps over the lazy cat
В ответах на:
I want to write the whole output to the file, a copy of the original with the changes made.
Вы можете либо перенаправить на файл, например
sed '4{ s/fox/elephant/; s/dog/cat/}' infile > modified_file
Или изменить в -место с флагом -i
:
sed -i '4{ s/fox/elephant/; s/dog/cat/}' infile
... или сделайте резервную копию исходного файла и запишите изменения с тем же именем исходного файла.
sed -i.backup '4{ s/fox/elephant/; s/dog/cat/}' infile
Или командой w
:
sed '4{ s/fox/elephant/; s/dog/cat/ }; w modified_file' infile
Если вы хотите написать только те строки, что s
подстановка команд прошла успешно (, а это не то, о чем вы просите в настоящее время ), с помощью флага w
вы можете сделать:
sed '4{ s/fox/elephant/; s/dog/cat/w modified_file
}' infile
But where do I put the w substitution flag if I'm using multiple commands and want the results wrote to a file?
Флаг w
должен заканчиваться символом новой строки или должен быть последним элементом (, включая аргумент it )в сценарии sed. Если будут найдены пробелы, комментарии или точки с запятой, они будут включены в имя файла.
Не путайте флаг w
, связанный с подстановкой команды s
(s///w
), и команду w
. Они похожи, но флаг w
используется только в том случае, если выполняется замена. Обратите внимание, что команда w
может использоваться условно или безоговорочно в зависимости от сценариев использования sed ().
Примечание :опцияi
(--in-place
)не указана в POSIX.
Первый пример
prompt% sed -i.back -e "/$regex/w output" -e "/$regex/d" input
Второй пример
prompt% sed -i.back "/$regex/ {
w output
d;}" input
Кто-то может столкнуться с проблемой в вашем случае(см. ниже ), поскольку в одной и той же строке ввода выполняется несколько подстановок.
prompt% sed -n '4 {
s/fox/wolf/w output
s/dog/bear/w output
}' input
Изменена только одна входная строка, но выходной файл содержит две строки.
The quick brown wolf jumps over the lazy dog
The quick brown wolf jumps over the lazy bear
Этот результат неудобен, поскольку вводит в заблуждение.
I want to write the whole output to the file, a copy of the original with the changes made.
Мое решение позволяет создать резервную копию исходного файла (input.back
), применить изменения в исходном файле(input
)и записать потенциальные замены в другой файл(output
). Этот алгоритм использует команду w
.
prompt% sed -i.back -nE '4!p # print line except 4th
4!d # delete line except 4th
/fox|dog/!p # print line if no "fox" or no "dog"
/fox|dog/!d # don't delete line if "fox" or "dog"
s/fox/wolf/ # substitution occurs if "fox"
s/dog/bear/ # substitution occurs if "dog"
p # if a substitution then print 4th line
w output' input # if a change then save 4th line in "output"
Команда /fox|dog/!d
немедленно запускает следующий цикл, если fox
или dog
не найдено (ни одно из них ). Поэтому, если ключевое слово не найдено, следующие команды (s///
, p
,w
)для текущей строки не обрабатываются.