Игнорировать все, кроме текста, при сравнении файлов с помощью diff?

Прежде всего, если речь идет о файле / etc / passwd , НЕ используйте это решение; используйте usermod .

Допустим, вы хотите преобразовать третье поле в newvalue2 для user007 . Вы можете сделать это так:

awk -F: -v OFS=: '$1 == "user007" {$3 = "newvalue2"} {print}' inputfile > outputfile

Если вы специально хотите настроить для этого функцию оболочки, вы можете (хотя я лично не стал бы беспокоиться).

myfunc() {
  [ "$#" -eq 2 ] ||
    { printf '%s\n' 'Usage: myfunc  ' 'Assigns given GPA to USER (in column 5 of "~/students.dat")'
      return 1;}

  local mytempfile
  mytempfile="$(mktemp)"

  awk -F: -v OFS=: -v user="$1" -v gpa="$2" '$1 == user {$5 = gpa} {print}' ~/students.dat > "$mytempfile" &&
    mv "$mytempfile" ~/students.dat
}

Однако это НЕ то, что я бы сделал для НАСТОЯЩИХ данных , только для временных или «игрушечных» данных, никому не нужных, кроме меня. Он намного более хрупкий, чем должен быть. CSV не заменяют правильную базу данных.

Если вы выбираете решение на основе CSV, по крайней мере, убедитесь, что у вас есть регулярные резервные копии и НАМНОГО лучше проверяйте ошибки, чем показано выше; например, вы можете захотеть проверить правильность предоставленного имени «пользователя» или выдать ошибку, если пользователь не найден в CSV-файле, или выполнить проверку целостности данных - например, проверку диапазона - по предоставленному GPA. Но все это лучше было бы делать с реальной базой данных.

Вы можете очень легко настроить песочницу PostgreSQL и начать экспериментировать с ней, чтобы узнать больше о реальных базах данных и о том, что вы можете с ними делать.

2
16.08.2016, 08:04
2 ответа

Вы можете предварительно обработать файлы, а затем сравнить поток. Например. используйте tr , чтобы удалить все пробелы и символы новой строки.

diff <( tr -d ' \n' <file1 ) <( tr -d ' \n' <file2)

Примеры файлов: a и b , которые разделяют текст, но не пробелы и позиции новой строки:

cat a
1
2
3

cat b
1 2 3

diff -sq a b
Files a and b differ

diff -sq <( tr -d ' \n' <a ) <( tr -d ' \n' <b )
Files /dev/fd/63 and /dev/fd/62 are identical

Обратите внимание, что

  1. Это не будет отличаться между этими словами и эти слова
  2. Вы должны внимательно следить за тем, какие символы вы удаляете. Имена выходных файлов
  3. diff являются именами потоков, а не именами файлов

См. man tr для специальных символов, таких как табуляция и т. д. (возможно, набор [: space:] лучше всего соответствует вашим потребностям)

1
27.01.2020, 22:19

Если вы хотите просто игнорировать все белые -пробелы (вкладки, пробелы:-w)и пустые символы новой строки (-B), тогда (при условии, что GNU diff):

$ diff -B -w file1 file2

Или, используя длинную опцию (, см. man diff),

$ diff --ignore-blank-lines --ignore-all-space file1 file2

Это в основном тот же (, но более описательный вывод ), что и предварительная -обработка файла, например, с помощьюtr:

$ diff <(tr -d '[:space:]' < file1)  <(tr -d '[:space:]' < file2)
0
18.03.2021, 02:23

Теги

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