Могу ли я предложить вам использовать ex
, предшественницу и не -визуальную форму vi
, для ваших требований к множественной адресации:
ex file.txt <<'EOF'
0/^user://password:/s/:.*/: '!!'/
0/^something else://subline to change:/s/:.*/: new value/
x
EOF
0
означает строку 0; то есть начните этот поиск с начала файла.
/^user:/
— это адрес. Он работает аналогично адресам Sed или Awk, за исключением того, что в ex
вы можете указать дополнительный адрес , который берется из строки, указанной первым адресом. (Вы даже можете использовать обратную адресацию.)
/password:/
— это другой адрес. Таким образом, это указывает строку, найденную путем поиска шаблона password:
вперед от точки, где был найден шаблон ^user:
.
Команда s/old/new/
работает так же, как в Sed.
x
означает сохранение и выход.
Все это завернуто в Bash "вот документ".
Как указано в комментариях, первоначальной целью было перебрать список таких пользователей, а не жестко кодировать статического пользователя.
Для этого предположим, что текстовый файл userlist.txt
, содержащий, например,.
user1
user2
Далее, если вы хотите выполнить одну и ту же замену для каждого пользователя (, а именно, установив для поля «пароль» значение '!!'
), просто используйте sed для преобразования списка пользователей в команду ex
.
Обратите внимание, что поскольку !!
будет развернут в интерактивной оболочке, для интерактивного использования сначала запустите
set +H
Тогда:
< userlist.txt sed -e "s_.*_0/^&://password:/s/:.*/: '!!'/_" -e $'$a\\\nx' | ex file.txt
Легко, как пирог. ;)
Демонстрация:
$ cat file.txt
user1:
ensure: 'present'
uid: '666'
gid: '100'
home: '/home/example1'
comment: ''
password_max_age: '99999'
password_min_age: '0'
shell: '/bin/false'
password: '1'
user2:
ensure: 'present'
uid: '667'
gid: '100'
home: '/home/example2'
comment: ''
password_max_age: '99999'
password_min_age: '0'
shell: '/bin/false'
password: '2'
user3:
ensure: 'present'
uid: '668'
gid: '100'
home: '/home/example3'
comment: ''
password_max_age: '99999'
password_min_age: '0'
shell: '/bin/false'
password: '3'
user4:
ensure: 'present'
uid: '669'
gid: '100'
home: '/home/example4'
comment: ''
password_max_age: '99999'
password_min_age: '0'
shell: '/bin/false'
password: '4'
$ cat userlist.txt
user3
user2
$ set +H
$ < userlist.txt sed -e "s_.*_0/^&://password:/s/:.*/: '!!'/_" -e $'$a\\\nx' | ex file.txt
$ cat file.txt
user1:
ensure: 'present'
uid: '666'
gid: '100'
home: '/home/example1'
comment: ''
password_max_age: '99999'
password_min_age: '0'
shell: '/bin/false'
password: '1'
user2:
ensure: 'present'
uid: '667'
gid: '100'
home: '/home/example2'
comment: ''
password_max_age: '99999'
password_min_age: '0'
shell: '/bin/false'
password: '!!'
user3:
ensure: 'present'
uid: '668'
gid: '100'
home: '/home/example3'
comment: ''
password_max_age: '99999'
password_min_age: '0'
shell: '/bin/false'
password: '!!'
user4:
ensure: 'present'
uid: '669'
gid: '100'
home: '/home/example4'
comment: ''
password_max_age: '99999'
password_min_age: '0'
shell: '/bin/false'
password: '4'
$
Вуаля.
для сохраняемости объявите переменную в rc
или исходный файл вrc
echo 'source /home/ec2-user/file1' >> /home/ec2-user/.bashrc
«Переменная, хранящаяся в файле» на самом деле ничего не значит.Большинство видов переменных существуют в состоянии запущенного процесса (оболочки или другой программы ). (Существует разница между переменными окружения, переменными оболочки и т. д., но здесь это не важно. )Каждый процесс имеет собственный набор переменных (, за исключением того, что копии переменных среды наследуются подпроцессами при их создании ).
Вы можете определить переменную в процессе оболочки с помощью команды типа name="Jhon"
, но она определяет эту переменную только в этом конкретном процессе оболочки, а не в каком-либо другом. Кроме того, это исполняемая команда ; определение имеет место только тогда, когда оно выполняется (, а не, например. когда он находится в файле ), и его можно изменить позже, выполнив другую команду, например name="Rho"
или unset name
.
Обычный способ определить переменную «везде» — поместить команду для ее определения в файл инициализации оболочки, например ~/.bashrc. Но это определение выполняется только в том случае, если оболочка запускает команды из этого файла при запуске; например, оболочка bash для входа в систему будет запускать ~/.bash _profile (или ~/.bash _login или ~/.profile )вместо ~/.bashrc; оболочки, отличные от bash (, такие как zsh и dash ), будут запускать разные файлы инициализации.