вырезать из файла пустые строки (скрипт bash)

Вы можете использовать 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
2
29.12.2020, 01:31
3 ответа

Ваш код, улучшенный:

awk -i inplace '$2 ~ /[0-9]/ || $3 ~ /[0-9]/ { print $2, $3 }' "$output_file"

Предполагается, что вы используете GNU awk4.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способен.

4
18.03.2021, 22:40

Проблема с вашим кодом в том, что вы сохраняете результаты в переменной 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, и я бы предложил использовать один из вариантов из приведенной выше темы. ТАКЖЕ:этот массив поместит любое слово в отдельный элемент массива -, таким образом, полностью удалив вашу структуру новой строки ввода.

1
18.03.2021, 22:40

С помощью @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
-1
18.03.2021, 22:40

Теги

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