Прочитайте файл построчно с помощью awk, чтобы заменить символы в определенных номерах строк.

Один из популярных способов напомнить себе, что вы работаете в привилегированном режиме, — настроить приглашение оболочки так, чтобы ваше имя пользователя отображалось красным цветом. Большинство подсказок изменится на #при запуске от имени пользователя root, но также полезно видеть «опасный» цвет, чтобы знать, что вы должны соблюдать осторожность.

Другая идея состоит в том, чтобы максимально использовать принцип наименьших привилегий. Используйте такой инструмент, как sudo, чтобы ограничить возможность вашего пользователя запускать только подмножество команд (в обычном режиме ). Это также является краеугольным камнем патча selinux, который реализует обязательный контроль доступа (MAC )к системным ресурсам. Некоторым кажется, что с selinux непомерно сложно работать, но если хорошо его изучить, это очень полезный инструмент.

Как уже говорили другие, абсолютно безопасно работать под именем rootневозможно, поэтому лучше иметь регулярные резервные копии и какие-то процедуры на случай худшего. Мы все совершаем ошибки, но если вы способны оправиться от них, ошибки не будут стоить вам так дорого.

Это может быть слишком широко для вашего приложения,но посмотрите вскрытие GitLab об их инциденте с повреждением базы данных в прошлом году. В частности, здесь приведены некоторые шаги, которые они предприняли для настройки своего PS1, чтобы указать «безопасность» их среды.

2
24.04.2020, 10:16
3 ответа

Есть возможность чтения строк из файла с номерами строк напрямую в переменную в awk через getline (при условии, что номера строк отсортированы):

getline var <"filename"

Весь сценарий будет представлять собой один единственный вызов awk следующим образом:

awk -v f1='./LineNumbers.file' '
       NR >var+0 {    rc=getline var <f1;
                      if(rc<0){  stderr = "cat 1>&2";
                                 print "error reading",f1 | stderr;
                                 close(stderr);
                                 exit 1
                              }
                 }
       NR==var+0 {    sub(/0\/0/,"./.")
                 }
     1' BEFORE_File.txt

Конечно, вы можете перенаправить вывод в любой файл, который вам нравится.

0
19.03.2021, 02:26

Посмотрим, сработает ли это для вас:

awk '{ 
  if ( NR == FNR ) { 
    n[$1] = 0 
  } else { 
    if ( FNR in n ) { 
      gsub(/^0\/0$/, "./.", $0) 
    } 
    print 
  } 
}' LineNumbers.file BEFORE_File.txt > AFTER_File.txt

Выход:

./.
./.
0/1
0/1
./.
0/0
0/0
5
19.03.2021, 02:26

Учитывая, что ваш ввод на самом деле выглядит как blabla 4858 ABC 0/0:4,3,2 0/1:4,3,2, а не пример, который вы разместили в своем вопросе, все, что вам нужно, это:

awk 'NR==FNR{a[$1]; next} FNR in a{sub("0/0","./.")} 1' LineNumbers.file BEFORE_File.txt >AFTER_File.txt

Для вашего следующего вопроса, пожалуйста, опубликуйте образец ввода, который выглядит как ваш реальный ввод, чтобы избежать ответов, которые будут слишком простыми или более сложными, чем необходимо, и/или работать только с входными данными, которых у вас на самом деле нет.

Не делайте этого, так как это плохой подход во многих отношениях, но, к вашему сведению, если бы вы использовали цикл оболочки, как в вашем вопросе, вы бы написали его как:

myFileTmp=$(mktemp)
cp BEFORE_File.txt AFTER_File.txt
while IFS= read -r line
do
    awk -v var="${line}" '
        FNR==var { sub("0/0", "./.") } { print }
    ' AFTER_File.txt > "$myFileTmp" &&
    mv "$myFileTmp" AFTER_File.txt
done < LineNumbers.file

Также по сценарию в вашем вопросе-"\.\/\."в вашем gsub ()есть строка. Вам не нужно экранировать метасимволы регулярных выражений в строках, только в регулярных выражениях. То же самое для /. Все, что вам нужно написать, это "./.". См. Почему использование цикла оболочки для обработки текста считается плохой практикой? ,http://porkmail.org/era/unix/award.htmlиhttps://mywiki.wooledge.org/Quotesдля некоторых других проблем с вашим скриптом, помимо вашей проблемы.

2
19.03.2021, 02:26

Теги

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