Как читать строку из файла и сравнивать с каждой строкой второго файла

Я создаю сценарий установки Post OS, который будет включать раздел Hardening. И в этом разделе упрощения он будет читать параметры ядра из файла A и сравнить с файлом /etc/sysctl.conf, и если параметры недоступны в sysctl.conf, то он добавит его в sysctl.conf.

Параметры в пользовательском файле

################## Hardening ############################ kernel.exec-shield = 1 kernel.randomize_va_space = 1 net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.icmp_ignore_bogus_error_responses = 1 net.ipv4.tcp_syncookies = 1 net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.default.log_martians = 1 net.ipv4.tcp_timestamps = 0 net.ipv6.conf.all.accept_redirects = 0 net.ipv6.conf.default.accept_redirects = 0 ########################################################## 

Теперь я добавил эти строки для Hardening.

 for i in $(cat /etc/sysctl.conf) do if ! grep -Fxq " $i " /etc/sysctl.conf then echo -e "$i" > ~/testfile fi done 

Проблема с этим заключается в том, что он обрабатывает каждое пространство в параметрах ядра как пространственную линию, и проблема начинается с самого начала в «для i в $ (cat /etc/sysctl.conf)»

И это отладочная информация

 ./LinuxHardening.sh ++ date + LOGDATE='Mon Feb 9 07:58:07 EST 2015' + echo Mon Feb 9 07:58:07 EST 2015 + tee HardeningLog Mon Feb 9 07:58:07 EST 2015 + echo -e '\n############ Kernel Hardening ############' + tee -a HardeningLog ############ Kernel Hardening ############ ++ cat kernelparms + for i in '$(cat kernelparms)' + grep -Fxq '##################' /etc/sysctl.conf + echo -e '##################' + for i in '$(cat kernelparms)' + grep -Fxq Hardening /etc/sysctl.conf + echo -e Hardening + for i in '$(cat kernelparms)' + grep -Fxq '############################' /etc/sysctl.conf + echo -e '############################' + for i in '$(cat kernelparms)' + grep -Fxq kernel.exec-shield /etc/sysctl.conf + echo -e kernel.exec-shield + for i in '$(cat kernelparms)' + grep -Fxq = /etc/sysctl.conf + echo -e = + for i in '$(cat kernelparms)' + grep -Fxq 1 /etc/sysctl.conf + echo -e 1 + for i in '$(cat kernelparms)' + grep -Fxq kernel.randomize_va_space /etc/sysctl.conf + echo -e kernel.randomize_va_space + for i in '$(cat kernelparms)' + grep -Fxq = /etc/sysctl.conf + echo -e = + for i in '$(cat kernelparms)' + grep -Fxq 1 /etc/sysctl.conf + echo -e 1 + for i in '$(cat kernelparms)' + grep -Fxq net.ipv4.icmp_echo_ignore_broadcasts /etc/sysctl.conf + echo -e net.ipv4.icmp_echo_ignore_broadcasts + for i in '$(cat kernelparms)' + grep -Fxq = /etc/sysctl.conf + echo -e = + for i in '$(cat kernelparms)' + grep -Fxq 1 /etc/sysctl.conf + echo -e 1 + for i in '$(cat kernelparms)' + grep -Fxq net.ipv4.icmp_ignore_bogus_error_responses /etc/sysctl.conf + echo -e net.ipv4.icmp_ignore_bogus_error_responses + for i in '$(cat kernelparms)' + grep -Fxq = /etc/sysctl.conf + echo -e = + for i in '$(cat kernelparms)' + grep -Fxq 1 /etc/sysctl.conf + echo -e 1 + for i in '$(cat kernelparms)' + grep -Fxq net.ipv4.tcp_syncookies /etc/sysctl.conf + echo -e net.ipv4.tcp_syncookies + for i in '$(cat kernelparms)' + grep -Fxq = /etc/sysctl.conf + echo -e = + for i in '$(cat kernelparms)' + grep -Fxq 1 /etc/sysctl.conf + echo -e 1 + for i in '$(cat kernelparms)' + grep -Fxq net.ipv4.conf.all.log_martians /etc/sysctl.conf + echo -e net.ipv4.conf.all.log_martians + for i in '$(cat kernelparms)' + grep -Fxq = /etc/sysctl.conf + echo -e = + for i in '$(cat kernelparms)' + grep -Fxq 1 /etc/sysctl.conf + echo -e 1 + for i in '$(cat kernelparms)' + grep -Fxq net.ipv4.conf.all.accept_redirects /etc/sysctl.conf + echo -e net.ipv4.conf.all.accept_redirects + for i in '$(cat kernelparms)' + grep -Fxq = /etc/sysctl.conf + echo -e = + for i in '$(cat kernelparms)' + grep -Fxq 0 /etc/sysctl.conf + echo -e 0 + for i in '$(cat kernelparms)' + grep -Fxq net.ipv4.conf.all.rp_filter /etc/sysctl.conf + echo -e net.ipv4.conf.all.rp_filter + for i in '$(cat kernelparms)' + grep -Fxq = /etc/sysctl.conf + echo -e = + for i in '$(cat kernelparms)' + grep -Fxq 1 /etc/sysctl.conf + echo -e 1 + for i in '$(cat kernelparms)' + grep -Fxq net.ipv4.conf.all.send_redirects /etc/sysctl.conf + echo -e net.ipv4.conf.all.send_redirects + for i in '$(cat kernelparms)' + grep -Fxq = /etc/sysctl.conf + echo -e = + for i in '$(cat kernelparms)' + grep -Fxq 0 /etc/sysctl.conf + echo -e 0 + for i in '$(cat kernelparms)' + grep -Fxq net.ipv4.conf.default.accept_redirects /etc/sysctl.conf + echo -e net.ipv4.conf.default.accept_redirects + for i in '$(cat kernelparms)' + grep -Fxq = /etc/sysctl.conf + echo -e = + for i in '$(cat kernelparms)' + grep -Fxq 0 /etc/sysctl.conf + echo -e 0 + for i in '$(cat kernelparms)' + grep -Fxq net.ipv4.conf.default.log_martians /etc/sysctl.conf + echo -e net.ipv4.conf.default.log_martians + for i in '$(cat kernelparms)' + grep -Fxq = /etc/sysctl.conf + echo -e = + for i in '$(cat kernelparms)' + grep -Fxq 1 /etc/sysctl.conf + echo -e 1 + for i in '$(cat kernelparms)' + grep -Fxq net.ipv4.tcp_timestamps /etc/sysctl.conf + echo -e net.ipv4.tcp_timestamps + for i in '$(cat kernelparms)' + grep -Fxq = /etc/sysctl.conf + echo -e = + for i in '$(cat kernelparms)' + grep -Fxq 0 /etc/sysctl.conf + echo -e 0 + for i in '$(cat kernelparms)' + grep -Fxq net.ipv6.conf.all.accept_redirects /etc/sysctl.conf + echo -e net.ipv6.conf.all.accept_redirects + for i in '$(cat kernelparms)' + grep -Fxq = /etc/sysctl.conf + echo -e = + for i in '$(cat kernelparms)' + grep -Fxq 0 /etc/sysctl.conf + echo -e 0 + for i in '$(cat kernelparms)' + grep -Fxq net.ipv6.conf.default.accept_redirects /etc/sysctl.conf + echo -e net.ipv6.conf.default.accept_redirects + for i in '$(cat kernelparms)' + grep -Fxq = /etc/sysctl.conf + echo -e = + for i in '$(cat kernelparms)' + grep -Fxq 0 /etc/sysctl.conf + echo -e 0 + for i in '$(cat kernelparms)' + grep -Fxq '##########################################################' /etc/sysctl.conf + echo -e '##########################################################' 

  • Выровнять столбцы в файле ASCII
  • Обнуление / усечение десятичных знаков в столбце
  • Замените номера в файле1 соответствующей строкой в ​​файле2
  • Как перемещаться по файлу и извлекать слова, используя их индекс?
  • Создание файла fasta из 2 разных файлов
  • Временное отображение текста в терминале, возможно небольшая разметка (полужирный, цвета). AKA "играть .srt субтитры"
  • найти совпадающие URL-адреса в строке, а затем сократить их до имени домена
  • Слияние большого набора данных самым быстрым способом
  • 5 Solutions collect form web for “Как читать строку из файла и сравнивать с каждой строкой второго файла”

    Почему бы не читать строки за строкой, используя:

     while read -r line do if ! grep -Fxq " $line " /etc/sysctl.conf then echo -e "$line" >> ~/testfile fi done </etc/sysctl.conf 

    и Замените> с помощью >>.

    Попробуйте что-нибудь вроде:

     while read i do if ! grep -Fxq " $i " /etc/sysctl.conf then echo -e "$i" >> ~/testfile fi done<kernelparms 

    С awk и ассоциативными массивами :

     awk '!/^($|#)/{arr[$1]=$0}END{for(param in arr) print arr[param]}' /etc/sysctl.conf custom.conf 

    если порядок:

     awk '!/^($|#)/{ arr[$1] = $0 } END { for(key in arr) print arr[key] }' /etc/sysctl.conf custom.conf | sort > hardened.conf 

    !/^($|#)/ – игнорировать прокомментированные или пустые строки
    {arr[$1]=$0} – хранить каждую строку в arr, связывая ее с параметром kernel; строка обновляется каждый раз, когда видит один и тот же параметр (т. е. из custom.conf поскольку это последний файл для чтения)
    END{for(param in arr) print arr[param]} – после того, как все данные были прочитаны, распечатайте соответствующую строку для каждого параметра ядра.

    Если я правильно понимаю ваш вопрос, ваша проблема заключается в расширении выражения $ (cat), которое разбивается на пробелы, чтобы цикл повторялся по всем полям данных вместо строк. Чтобы исправить это, вы можете использовать этот подход …

     while IFS= read -ri do ...your loop code operating on $i here... done < /etc/sysctl.conf 

    Установите IFS=$'\n' и он не будет рассматривать пробелы как новые строки.

    Linux и Unix - лучшая ОС в мире.