Отредактируйте значения в текстовом файле с помощью команды sed / awk / grep

Кавычки не вложены. Вы пытаетесь передать ssh удаленную команду в виде строки с двойными кавычками, содержащей аргумент в одинарных кавычках для awk, а внутри этого аргумента несколько строк с двойными кавычками. Но оболочка воспринимает каждую из этих двойных кавычек как начало или конец строки с двойными кавычками, что вносит путаницу.

В частности, когда вы используете "df -khP | column -t | awk '{print $5 " " $1 " " $2}'" в списке аргументов к ssh, он разбирается на несколько отдельных строк с кавычками. Первая - "df -khP | column -t | awk '{print $5', и поскольку $variable подстановка производится внутри строк с двойными кавычками, а скрипт не получил 5 аргументов, часть $5 заменяется ничем, давая "df -khP | column -t | awk '{print ". Следующим является " $1 ", который расширяется до "192.168.5.210" (потому что это первый аргумент скрипта). Наконец, есть " $2}'", который расширяется до " }'", потому что второго аргумента нет. ssh затем вставляет их вместе с пробелами между ними, выдавая `df -khP | column -t | awk '{print 192.168.5.210 }' в качестве выполняемой команды. Совсем не то, что вы хотели.

Чтобы все работало правильно, вам нужно экранировать (с помощью обратных слешей) определенные символы внутри того, что должно быть одной длинной строкой с двойными кавычками. В частности, все двойные кавычки (чтобы они не завершали строку в кавычках) и знаки доллара (чтобы они не расширялись как параметры или что-то еще). Любые обратные кавычки или обратные слэши также должны быть экранированы, если они есть. Таким образом, вот команда, которая вам нужна:

ssh 192.168.5.209 ssh root@$STRIP "df -khP | column -t  | awk '{print \$5 \" \" \$1 \" \" \$2}'"

BTW, если я правильно понял, причина, по которой awk выводит то, что он делает, заключается в том, что он разбирает 192.168.5.210 как три действительных числа, 192.168, .5 и .210, и печатает их (с ведущими нулями, добавленными там, где это необходимо, и с отстающими нулями, которые не имеют значения) как "192.168", "0.5" и "0.21". Но он не печатает пробелы между ними, поэтому получается "192.1680.50.21".

9
03.12.2016, 17:09
5 ответов

Вот немного более идиоматический вариант AWK для обработки current.txt ( второй ответ Стива еще более идиоматичен!):

awk '/^To(|min|max) / { print $1, $2 + 1; next } 1' current.txt

Это ищет строки, начинающиеся с К , за которым следует ничего, min или max , за которым следует пробел; для сопоставления строк он печатает первое поле и второе поле с приращением, разделенные разделителем поля вывода по умолчанию (пробелом). Затем он переходит к следующей строке. Все остальные строки печатаются как есть ( 1 - это сокращение для этого в AWK).

Обратите внимание, что перезапись файла новыми значениями, вероятно, не лучшая идея: вы не узнаете, были ли значения исправлены или нет ... Если вы каждый раз извлекаете файл с устройства, это не так. подать заявление.

То же самое относится и к ws2308.log , поэтому давайте просто каждый раз обрабатывать его полностью:

$ awk 'NF >= 5 { $5 = $5 + 1 } 1' ws2308.log
20161203150600 2016-Dec-03 15:06:00 11.8 -0.1 -3.2 65 87 0.0 157.5 SSE -1.1 569.80 1015.700
20161203152100 2016-Dec-03 15:21:00 12.3 -0.1 -3.2 64 87 0.0 157.5 SSE -1.1 569.80 1015.600
20161203153600 2016-Dec-03 15:36:00 12.2 -0.2 -3.3 64 87 0.0 135.0 SE -1.2 569.80 1015.700

Если вам нужна только последняя строка:

$ awk 'NF >= 5 { $5 = $5 + 1; lastline = $0 } END { print lastline }' ws2308.log
20161203153600 2016-Dec-03 15:36:00 12.2 -0.2 -3.3 64 87 0.0 135.0 SE -1.2 569.80 1015.700

или если вам нужен файл с изменена только последняя строка :

$ awk 'length(prevline) > 0 { print prevline } NF >= 5 { prevline = $0; $5 = $5 + 1; lastline = $0 } END { print lastline }' ws2308.log
20161203150600 2016-Dec-03 15:06:00 11.8 -1.1 -3.2 65 87 0.0 157.5 SSE -1.1 569.80 1015.700 
20161203152100 2016-Dec-03 15:21:00 12.3 -1.1 -3.2 64 87 0.0 157.5 SSE -1.1 569.80 1015.600 
20161203153600 2016-Dec-03 15:36:00 12.2 -0.2 -3.3 64 87 0.0 135.0 SE -1.2 569.80 1015.700
12
27.01.2020, 20:04

Вот одно решение. Для любых строк, которые начинаются с «To», «Tomin» или «Tomax», за которыми следует пробел, выведите первое поле, а затем второе поле с увеличением на 1. В противном случае просто распечатайте всю строку.

$ awk '{if(/^(To|Tomin|Tomax) /){print $1 " " $2+1}else{print $0}}' w.txt
Date 2016-Dec-03
Time 10:30:29
Ti 11.9
Timin 11.6
Timax 27.7
TTin 10:34
DTimin 2016-01-19
TTimax 00:44
DTimax 2016-08-28
To -1.4
Tomin -3.8
Tomax 38.4
TTomin 06:46
DTomin 2016-02-18
TTomax 16:13
DTomax 2016-07-19
$
10
27.01.2020, 20:04

Это выполнит работу:

  1. Сначала пройдутся все строки
  2. Затем проверьте первый элемент и проверьте, соответствует ли он тому, что вы хотите.
  3. Затем, если он совпадает, распечатайте его и добавьте +1 к следующему элементу в строке
  4. Иначе просто распечатайте его и выведите следующий элемент

     awk '{
    for (i = 1 ; i <= NF; i ++) {
    t + = $ i; if (i == 1) {
    if ($ i == "To" || $ i == "Tomin" || $ i == "Tomax") {
    printf "% s", $ i; 
    print $ (i + 1) +1;} 
     {{1} } else {
    print $ 0 
    } 
    } 
    }; 
    } 'current.txt 
     

ВЫХОД

Date 2016-Dec-03
Time 10:30:29
Ti 11.9
Timin 11.6
Timax 27.7
TTin 10:34
DTimin 2016-01-19
TTimax 00:44
DTimax 2016-08-28
To -1.4
Tomin -3.8
Tomax 38.4
TTomin 06:46
DTomin 2016-02-18
TTomax 16:13
DTomax 2016-07-19
2
27.01.2020, 20:04

Другой подход, слегка golfed.

$ awk '/^To/{$2++}1' w.txt
Date 2016-Dec-03
Time 10:30:29
Ti 11.9
Timin 11.6
Timax 27.7
TTin 10:34
DTimin 2016-01-19
TTimax 00:44
DTimax 2016-08-28
To -1.4
Tomin -3.8
Tomax 38.4
TTomin 06:46
DTomin 2016-02-18
TTomax 16:13
DTomax 2016-07-19
$
5
27.01.2020, 20:04

Подход Perl:

perl -i -ape '/^To/ && s/$F[1]/$F[1]+1/e' file

-i заставляет его перезаписывать исходный файл, поэтому он ничего не печатает, он изменяет файл напрямую.

-a заставляет perl действовать как awk , разделяя его ввод на whitesapce (или что-то еще, заданное -F ) в массив @F . Таким образом, второе поле будет $ F [1] , потому что массивы начинают отсчет с 0. Таким образом, сценарий заменит второе поле на себя, увеличенное на единицу, в строках, начинающихся с To .

5
27.01.2020, 20:04

Теги

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