Прежде всего, если речь идет о файле / 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 и начать экспериментировать с ней, чтобы узнать больше о реальных базах данных и о том, что вы можете с ними делать.
Вы можете предварительно обработать файлы, а затем сравнить поток. Например. используйте 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
Обратите внимание, что
этими словами
и эти слова
diff
являются именами потоков, а не именами файлов См. man tr
для специальных символов, таких как табуляция и т. д. (возможно, набор [: space:]
лучше всего соответствует вашим потребностям)
Если вы хотите просто игнорировать все белые -пробелы (вкладки, пробелы:-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)