sed с несколькими командами, я могу использовать w (запись) флаг?

Попробуйте / sbin / nologin в / etc / passwd , пользователь может выполнить.

1
10.09.2018, 09:49
3 ответа

На самом деле имеется два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

Q1

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

Q2

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
2
27.01.2020, 23:14

В ответах на:

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
2
27.01.2020, 23:14

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)для текущей строки не обрабатываются.

2
27.01.2020, 23:14

Теги

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