Вы можете использовать system()
в awk
для запуска любой команды, но вы не можете использовать его для смены каталога, так как он запускает команду в подоболочке, так что вы измените каталог в подоболочке, которая немедленно завершит работу. Команда будет выглядеть следующим образом:
pwd|awk '$0 == "/"{system("cd /tmp")}'
Но, как я уже сказал, это не сработает. Если вы добавите echo
перед командой, вы увидите, что она на самом деле выполняется, когда вы этого ожидаете :
$ cd /
$ pwd|awk '$0 == "/"{system("echo cd /tmp")}'
cd /tmp
$ cd /home
$ pwd|awk '$0 == "/"{system("echo cd /tmp")}'
Я думаю, что было бы лучше просто использовать оператор and if
:
if [ "${PWD}" = '/' ];then
cd /tmp
fi
Ваш код, улучшенный:
awk -i inplace '$2 ~ /[0-9]/ || $3 ~ /[0-9]/ { print $2, $3 }' "$output_file"
Предполагается, что вы используете GNU awk
4.1.0 или более позднюю версию (для опции -i inplace
). Код извлекает 2-е и 3-е поля из любой строки, где хотя бы одно из этих полей содержит цифру.
Без GNUawk
:
tmpfile=$(mktemp)
cp "$output_file" "$tmpfile"
awk '$2 ~ /[0-9]/ || $3 ~ /[0-9]/ { print $2, $3 }' "$tmpfile" >"$output_file"
rm -f "$tmpfile"
Другая формулировка программы awk
состоит в том, чтобы сбросить $0
во 2-е и 3-е поля, а затем выполнить проверку цифр:
awk -i inplace '{ $0 = $2 " " $3 }; /[0-9]/' "$output_file"
В вашем коде обнаружен ряд ошибок. То, о чем вы сами упоминаете, получая в конце все строки в одну строку, связано с использованием значения $result
без кавычек с echo
. Расширение $result
не заключено в кавычки, потому что вы по какой-то причине используете два набора двойных кавычек (две пустые строки )по обе стороны от расширения, ""$result""
.
Когда вы используете расширение переменной без кавычек, оболочка возьмет значение переменной и разделит его на любой пробел, табуляцию или символ новой строки, чтобы создать несколько слов. Затем каждое слово будет подвергаться подстановке имени файла. Полученные слова затем используются с echo -e
в вашем коде, который выводит каждый аргумент с пробелами в -между ними и новой строкой в самом конце.
Кроме того, вам не нужно помещать вывод команд в переменные. В этом случае просто перенаправление на файлы будет вполне нормально.
Ваша команда sed
вставляет строку \n
в начале каждой строки, заменяя любую серию цифр, отличных от -, которая оказывается первой в строке. Он не удаляет строки, не содержащие цифр. Для этого используйте выражение sed
/[0-9]/!d
. Но в этом нет необходимости, если вы выводите только строки со своим awk
скриптом, содержащим цифры (, что и мой код выше ).
Удивительно редко можно передать awk
в sed
или наоборот. awk
более чем способен делать то, на что sed
способен.
Проблема с вашим кодом в том, что вы сохраняете результаты в переменной bash
:
no_empty_lines=$(cat "$output_file" | awk NF)
Который (пропуская избыточный cat
), можно рассматривать как:
result=$(command that returns multi-line data)
Однако bash
превращает многострочные -строки в одну строку с пробелами.
Возможные способы: здесь -, что, как я полагаю, вам нужно, однако с bash
вашим результатом может быть массив:
no_empty_lines=( $(awk 'NF' "$output_file") )
Записи теперь ${no_empty_lines[0]}
, ${no_empty_lines[1]}
,...
Вызвать их циклом
for ((i=0;i<=${#no_empty_lines[@]}-1;i++)) ; do echo ${no_empty_lines[i]} ; done
Еще раз -это просто для того, чтобы показать вам, где ваш код дал сбой из-за bash
, и я бы предложил использовать один из вариантов из приведенной выше темы. ТАКЖЕ:этот массив поместит любое слово в отдельный элемент массива -, таким образом, полностью удалив вашу структуру новой строки ввода.
С помощью @roaima мне удалось решить проблему,
In your answer, result correctly holds multiline data. The problem comes when it's printed out: the variable isn't quoted (rcho ""$result"" is the same as echo $result) so the shell parses the result into multiple words, with newlines having been treated just like any other whitespace – roaima 6 hours ago
вот рабочее решение:
result=$(cat "$output_file"| awk '{print $2" "$3}' | sed 's/[^0-9]*//')
echo -e "$result" | awk NF > "$output_file"
Предполагая, что переменная была сохранена правильно, я удалил лишние кавычки при отображении «$result», затем передал их в «awk NF», который удаляет пустые строки и выводит их в файл.
теперь результат выглядит так:
> 135.121.9.256 6.2 > 135.121.160.50 7.5 > 135.121.106.10 10 > 135.121.9.66 commandFailed > 135.121.100.156 commandFailed