Ответ 1
Хорошо, у меня это есть.
awk '{printf "%s\0", $0}'
Или, используя ORS
,
awk -vORS=$'\0' //
Я работаю над оболочкой script, которая будет использоваться другими, и может заражать подозрительные строки. Он основан на awk, так как базовая мера отказоустойчивости, я хочу, чтобы awk выводил строки с нулевым завершением - команды, которые будут получать данные из awk, могут, таким образом, избежать определенного количества поломки из строк, которые содержат пробелы или не часто встречаются Английские символы.
К сожалению, из основной документации awk
я не понимаю, как сказать awk, чтобы напечатать строку, завершенную нулем ASCII вместо новой строки. Как я могу сказать awk, что я хочу строки с нулевым завершением?
Версии awk, которые могут быть использованы:
[[email protected]]$ awk --version
awk version 20070501
[[email protected]]$ awk -W version
mawk 1.3.3 Nov 1996, Copyright (C) Michael D. Brennan
[[email protected]]$ awk -W version
GNU Awk 3.1.7
В значительной степени это семейство версий awk
. Если нам нужно консолидироваться в версии, это, вероятно, будет GNU Awk, но ответы на все версии приветствуются, так как мне, возможно, придется работать над всеми этими awks. О, устаревшие скрипты.
Хорошо, у меня это есть.
awk '{printf "%s\0", $0}'
Или, используя ORS
,
awk -vORS=$'\0' //
Существует три варианта:
awk -vORS=$'\0'
, но: $'\0'
является конструкцией, специфичной для некоторых оболочек (bash, zsh). awk -vORS=$'\0'
не будет работать в большинстве старых оболочек.Существует возможность записать его как: awk 'BEGIN { ORS = "\0" } ; { print $0 }'
, но это не будет работать с большинством версий awk.
Печать (printf
) с символом \0
: awk '{printf( "%s\0", $0)}'
Печать непосредственно ASCII 0
: awk '{ printf( "%s%c", $0, 0 )}'
Тестирование всех альтернатив с помощью этого кода:
#!/bin/bash
test1(){ # '{printf( "%s%c",$0,0)}'|
a='awk,mawk,original-awk,busybox awk'
IFS=',' read -ra line <<<"$a"
for i in "${line[@]}"; do
printf "%14.12s %40s" "$i" "$1"
echo -ne "a\nb\nc\n" |
$i "$1"|
od -cAn;
done
}
#test1 '{print}'
test1 'BEGIN { ORS = "\0" } ; { print $0 }'
test1 '{ printf "%s\0", $0}'
test1 '{ printf( "%s%c", $0, 0 )}'
Получаем следующие результаты:
awk BEGIN { ORS = "\0" } ; { print $0 } a \0 b \0 c \0
mawk BEGIN { ORS = "\0" } ; { print $0 } a b c
original-awk BEGIN { ORS = "\0" } ; { print $0 } a b c
busybox awk BEGIN { ORS = "\0" } ; { print $0 } a b c
awk { printf "%s\0", $0} a \0 b \0 c \0
mawk { printf "%s\0", $0} a b c
original-awk { printf "%s\0", $0} a b c
busybox awk { printf "%s\0", $0} a b c
awk { printf( "%s%c", $0, 0 )} a \0 b \0 c \0
mawk { printf( "%s%c", $0, 0 )} a \0 b \0 c \0
original-awk { printf( "%s%c", $0, 0 )} a \0 b \0 c \0
busybox awk { printf( "%s%c", $0, 0 )} a b c
Как видно из вышеизложенного, первые два решения работают только в GNU AWK.
Наиболее портативным является третье решение: '{ printf( "%s%c", $0, 0 )}'
.
Никакое решение не работает правильно в "busybox awk".
Версии, используемые для этих тестов, были следующими:
awk> GNU Awk 4.0.1
mawk> mawk 1.3.3 Nov 1996, Copyright (C) Michael D. Brennan
original-awk> awk version 20110810
busybox> BusyBox v1.20.2 (Debian 1:1.20.0-7) multi-call binary.
Вы также можете подключить свой выход awk через tr:
awk '{...code...}' infile | tr '\n' '\0' > outfile
Просто протестированный, он работает, по крайней мере, на Linux и FreeBSD.
Если вы не можете использовать новые строки как разделители (например, если выходные записи могут содержать строки новой строки внутри), просто используйте какой-либо другой символ, который гарантированно не появится внутри записи, например. один с кодом 1:
awk 'BEGIN { ORS="\001" } {...code...}' | tr '\001' '\0'
Я решил распечатать ASCII 0 из awk. Я использую команду UNIX printf "\ 000"
echo | awk -v s='printf "\000"' '{system(s);}'