Кавычки не вложены. Вы пытаетесь передать 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".
Вот немного более идиоматический вариант 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
Вот одно решение. Для любых строк, которые начинаются с «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
$
Это выполнит работу:
Иначе просто распечатайте его и выведите следующий элемент
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
Другой подход, слегка 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
$
Подход Perl:
perl -i -ape '/^To/ && s/$F[1]/$F[1]+1/e' file
-i
заставляет его перезаписывать исходный файл, поэтому он ничего не печатает, он изменяет файл напрямую.
-a
заставляет perl
действовать как awk
, разделяя его ввод на whitesapce (или что-то еще, заданное -F
) в массив @F
. Таким образом, второе поле будет $ F [1]
, потому что массивы начинают отсчет с 0. Таким образом, сценарий заменит второе поле на себя, увеличенное на единицу, в строках, начинающихся с To
.