Manipulando caracteres NULL no shell

4

Existe uma maneira portátil de manipular caracteres NULL no shell?

Um exemplo típico seria dividir a saída de find ... -print0 com shell (e somente shell) em um pipe ou em um resultado de substituição de comando. Por portátil, quero dizer, idealmente, algo que não é tão poderoso quanto, por exemplo, bash ou zsh não se engasgou. Isso é possível em um "shell POSIX nua" (qualquer versão POSIX)?

    
por peterph 03.09.2015 / 23:11

3 respostas

3

O POSIX não prevê os utilitários padrão para lidar com a incorporação de texto null caracteres. A opção -print0 que você usa com find é, por si só, uma extensão GNU sem suporte de POSIX .

Uma maneira de lidar com um fluxo de dados contendo null s com POSIX shell script seria convertê-lo primeiro em texto real com od e processar esse texto.

Em qualquer caso, se você tiver GNU find , provavelmente terá outros utilitários GNU que não têm essa limitação em primeiro lugar.

    
por 04.09.2015 / 18:24
2

O Bash pode lidar com isso usando a opção read , por exemplo,

find . -print0 | while read -r -d '' line; do
    # something with $line
done

Não faço ideia se é POSIX, no entanto.

    
por 03.09.2015 / 23:17
0

Depois encontrar uma questão semelhante , aqui está o que eu tenho depois de algum tempo ... não tenho certeza se isso é possível em um shell POSIX. Tentei isso em Cygwin. Apenas por diversão, criei um problema com caracteres nulos.

O problema imaginário é o seguinte: você tem (alguns) arquivos que possuem caracteres nulos neles. Você não sabe exatamente quais arquivos são ou onde estão localizados. Sua tarefa é livrar-se de caracteres nulos de todos os arquivos possíveis.

Abaixo, o primeiro comando mostrará as linhas que possuem caracteres nulos, depois outro comando converte nulos em novas linhas (o último remove o arquivo temporário):

find . ! -type d -exec perl -ne '/
find . ! -type d -print > files.txt
while read line; do while read line2; do if grep -q "$line2" "$line"; then echo "$line" >> examination.txt; fi; done < with-null-lines.txt; done < files.txt
0/ and print;' {} \; > /tmp/null-lines tr -s '
uniq -c examination.txt | grep -v "1"
0' '\n' < /tmp/null-lines > with-null-lines.txt rm /tmp/null-lines

Depois disso, é uma questão de ler cada linha das linhas de resultado e descobrir em qual arquivo uma linha pertence. Para isso, primeiro salvo todos os arquivos que preciso passar e, em seguida, vejo se há uma linha correspondente neles:

uniq -d examination.txt > files-to-clean.txt
while read line; do ex -s +"%s/\%x00//g" -cwq $line; done < files-to-clean.txt

(Antes de executar novamente o ciclo, remova o arquivo "exam.txt")

Agora, contamos o número de ocorrências e, onde há mais de 1, há mais de um caractere nulo (com certeza, se houver apenas um, será mais difícil encontrá-lo).

tr -d '
tr -s '
find . ! -type d -exec perl -ne '/
find . ! -type d -print > files.txt
while read line; do while read line2; do if grep -q "$line2" "$line"; then echo "$line" >> examination.txt; fi; done < with-null-lines.txt; done < files.txt
0/ and print;' {} \; > /tmp/null-lines tr -s '
uniq -c examination.txt | grep -v "1"
0' '\n' < /tmp/null-lines > with-null-lines.txt rm /tmp/null-lines
0' '\n' < inputfile > outputfile
0' < inputfile > outputfile

E lá deve listar (a maioria) arquivos contendo caracteres nulos. Ignore o "com nulo-linhas.txt" um. Além disso, se houver textos idênticos em arquivos, você também poderá ver alguns arquivos inocentes que precisam ser removidos manualmente da lista.

  1. Se os caracteres nulos não estiverem no lugar de novas linhas, basta removê-los:

    uniq -d examination.txt > files-to-clean.txt
    while read line; do ex -s +"%s/\%x00//g" -cwq $line; done < files-to-clean.txt
    

    Ou com tr , para um arquivo:

    tr -d '
    tr -s '%pre%0' '\n' < inputfile > outputfile
    
    0' < inputfile > outputfile
  2. Para limpar um arquivo de caracteres nulos (desde que estejam todos localizados no lugar de novas linhas), use o comando:

    %pre%

    Não consultou muito como você poderia processar muitos arquivos com tr de uma só vez.

por 04.09.2015 / 18:06

Tags