corte com delimitador de 2 caracteres

1

Eu queria usar o cut to com um delimitador de dois caracteres para processar um arquivo com muitas linhas como esta:

1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0

Mas o corte permite apenas um único caractere.

Em vez de cut -d'..' , estou tentando awk -F'..' "{echo $1}" , mas não está funcionando.

Meu script:

wget -O output.txt http://www.unicode.org/Public/emoji/6.0/emoji-data.txt                                                                             
sed -i '/^#/ d' output.txt                        # Remove comments                                                                                   
cat output.txt | cut -d' ' -f1 | while read line ;                                                                                                    
  do echo $line | awk -F'..' "{echo $1}"                                                                                                             
done  
    
por Philip Kirkbride 22.08.2017 / 03:12

3 respostas

3

Exemplo de script de teste que funciona para mim:

#!/bin/sh

raw="1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0"

for r in $raw
do
    f1='echo "${r}" | cut -d'.' -f1'
    f2='echo "${r}" | cut -d'.' -f2'
    f3='echo "${r}" | cut -d'.' -f3'
    echo "field 1:[${f1}] field 2:[${f2}] field 3:[${f3}]"
done

exit

E a saída é:

field 1:[1F3C6] field 2:[] field 3:[1F3CA]
field 1:[1F3CF] field 2:[] field 3:[1F3D3]
field 1:[1F3E0] field 2:[] field 3:[1F3F0]

Editar

Depois de ler o comentário de Stéphane Chazelas e vincular a Q & A, eu reescrevi o acima para remover o loop .

Eu não consegui descobrir uma maneira de remover o loop e manter as partes como variáveis (por exemplo, $f1 , $f2 e $f3 na minha resposta original) que poderia ser passado ao redor. Ainda não sei o que foi exigido na pergunta original.

Primeiro, ainda usando cut :

#!/bin/sh
raw="1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0"

printf '%s\n' "${raw}" | cut -d'.' -f1,3

Qual será a saída:

1F3C6.1F3CA
1F3CF.1F3D3
1F3E0.1F3F0

Poderia substituir o . exibido por qualquer string usando o --output-delimiter=STRING .

Em seguida, com sed em vez de cut para dar mais controle à saída:

#!/bin/sh
raw="1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0"

printf '%s\n' "${raw}" | sed 's/^\(.*\)\.\.\(.*\)$/field 1 [] field 2 []/'

E isso será processado:

field 1 [1F3C6] field 2 [1F3CA]
field 1 [1F3CF] field 2 [1F3D3]
field 1 [1F3E0] field 2 [1F3F0]
    
por 22.08.2017 / 03:47
5
O separador de campo

awk é tratado como um regexp, desde que tenha mais de dois caracteres. .. como um regexp, significa quaisquer 2 caracteres. Você precisaria escapar do . com [.] ou com \. .

awk -F'[.][.]' ...
awk -F'\.\.' ...

(a barra invertida em si também precisa ser escapada (com alguns awks como gawk pelo menos) para a expansão \n / \b que o argumento para -F sofre).

No seu caso:

awk -F' +|[.][.]' '/^[^#]/{print $1}' < output.txt

Em qualquer caso, evite loops de shell para processar texto , observe que read não deve ser usado assim , que echo não deve ser usado para dados arbitrários e lembre-se de citar seu variáveis .

    
por 06.09.2017 / 16:44
2

Você pode usar o IFS para dividir cada linha descartando o campo entre os dois pontos:

#/bin/sh
while IFS=\. read a _ b
do
     echo "field one=[$a] field two=[$b]"
done < "file"

Executar:

$ ./script
field one=1F3C6 field two=1F3CA
field one=1F3CF field two=1F3D3
field one=1F3E0 field two=1F3F0

Supondo que o arquivo seja:

$ cat file
1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0
    
por 22.08.2017 / 05:04

Tags