Você pode adotar abordagens diferentes dependendo se awk trata RS como um único caractere (como o tradicional awk implementações faz) ou como uma expressão regular (como gawk ou mawk do). Arquivos vazios também são difíceis de serem considerados, pois awk tende a ignorá-los.
gawk , mawk ou outras awk implementações em que RS pode ser um regexp.
Nessas implementações (para mawk , cuidado com o fato de alguns sistemas operacionais como o Debian enviarem uma versão muito antiga em vez de um o moderno mantido por @ThomasDickey ), se RS contiver um único caractere, o separador de registro é esse caractere ou awk entra no modo de parágrafo quando RS está vazio ou trata RS como uma expressão regular caso contrário.
A solução é usar uma expressão regular que possivelmente não pode ser correspondida. Alguns vêm à mente como x^ ou $x ( x antes do início ou após o final). No entanto, alguns (particularmente com gawk ) são mais caros que outros. Até agora, descobri que ^$ é o mais eficiente. Ele só pode coincidir com uma entrada vazia, mas então não haveria nada para combinar.
Então, podemos fazer:
awk -v RS='^$' '{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...
Uma ressalva é que ele pula arquivos vazios (ao contrário de perl -0777 -n ). Isso pode ser resolvido com o GNU awk colocando o código em uma instrução ENDFILE . Mas também precisamos redefinir $0 em uma instrução BEGINFILE, pois, caso contrário, ela não seria redefinida após o processamento de um arquivo vazio:
gawk -v RS='^$' '
BEGINFILE{$0 = ""}
ENDFILE{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...
implementações tradicionais awk , POSIX awk
Nesses, RS é apenas um caractere, eles não têm BEGINFILE / ENDFILE , eles não têm a variável RT , eles geralmente também não podem processar o caractere NUL. / p>
Você poderia pensar que usar RS=' poderia funcionar, pois, de qualquer forma, eles não podem processar entradas que contenham o byte NUL, mas não, RS=''RS=' em implementações tradicionais é tratado como $'\U10FFFE' , que é o modo de parágrafo. .
Uma solução pode ser usar um caractere com pouca probabilidade de ser encontrado na entrada como sed . Em localidades de caractere multibyte, você pode até mesmo criar sequências de bytes que são muito improváveis de ocorrer, pois elas formam caracteres que não são atribuídos ou não caracterizam como $0 em locales UTF-8. Não é realmente infalível e você também tem problemas com arquivos vazios.
Outra solução pode ser armazenar toda a entrada em uma variável e processá-la na instrução END no final. Isso significa que você pode processar apenas um arquivo por vez:
awk '{content = content $0 RS}
END{$0 = content
printf "%s: <%s>\n", FILENAME, $0
}' file
Esse é o equivalente de gawk :
sed '
:1
$!{
N;b1
}
...' file1
Outro problema com essa abordagem é que, se o arquivo não estava terminando em um caractere de nova linha (e não estava vazio), ainda é adicionado arbitrariamente em RT no final (com RS , você contornar isso usando NR em vez de FNR no código acima). Uma vantagem é que você tem um registro do número de linhas no arquivo em %code% / %code% .