Como você usa o sed para editar um arquivo CSV?

2

Eu tenho um arquivo CSV como este:

hostname1 | role1 | environment | tag,list | |
hostname2 | role2 | environment | tag,list,longer | |
hostname3 | role3 | environment | | |

Eu preciso de uma expressão sed que adicione à coluna com as tags (a coluna th ) uma nova tag, se já não houver tags, e insira uma nova tag com uma vírgula se existem tags existentes. Eu tentei isso:

sed "s/\(^$server |.*|.*|\) \(.*|.*|$\)/ new,/" testfile.csv

onde o servidor é definido externamente da seguinte forma:

server="hostname2"

mas não funciona, e não lida com a vírgula se a lista de tags estiver vazia.

Como você faria isso com sed?

    
por Jason 03.01.2013 / 17:57

1 resposta

2

Um erro comum ao descobrir expressões regulares é pensar que elas podem ser usadas como analisador (e assim você vê perguntas como "como posso analisar um arquivo XML usando REGEXs?"). No entanto, você não pode inserir muita lógica dentro de uma expressão regular: para problemas complexos, como o seu, você precisa de um analisador ou mais de uma expressão regular.

Se você quiser seguir o caminho das expressões regulares, precisará de duas: uma para o caso de tags não vazias e outra para o campo de tags vazias. Os dois regex podem se parecer com os seguintes:

s/^(hostname123 \|.*?\|.*?\|\s*)(\S+\s*\|.*?\|)$/new,/
s/^(hostname123 ?\|.*?\|.*?\|)\s*(\|.*?\|)$/ new /

Essas duas expressões podem ser usadas com dois sed unidos:

sed 'expression1' | sed 'expression2'

ou melhor, com um comando da seguinte maneira:

sed -r -e '/^'"$server"' \|/ { s/^(.*?\|.*?\|.*?\|\s*)(\S+\s*\|.*?\|)$/new,/; s/^(.*?\|.*?\|.*?\|)\s*(\|.*?\|)$/ new / }' testfile.csv

Isso é mais eficiente do que usar dois sed s porque ele não analisa o arquivo duas vezes.

    
por Andrea Corbellini 03.01.2013 / 18:54