Estou procurando uma maneira de fazer o seguinte com um arquivo delimitado por barra vertical no UNIX, para CADA LINHA e não sei por onde começar:
- Procure um caractere em uma linha de texto (suponha que você esteja usando GREP?)
- Se encontrado, adicione algum texto no final dessa linha (usando SED?)
- Se não for encontrado, procure outro caractere na mesma linha
- Se encontrado, adicione texto no final da linha, caso contrário, não faça nada
- LOOP PARA TODAS AS LINHAS DO ARQUIVO
Qualquer indicação seria apreciada.
Responder1
Tudo isso é sed
trabalho, você não precisa de ferramentas extras:
Digamos que você queira adicionar foo
no final da linha contendo um f
e bar
no final das linhas sem f
, mas com umb
sed '/f/{
s/$/foo/
b
}
/b/s/$/bar/'
Você pode "endereçar" linhas com /pattern/
, portanto os comandos a seguir só serão executados se contiverem o padrão. Portanto, no exemplo, apenas as linhas que contêm um f
gatilho para a execução da s
substituição e o b
(o {}
grupo dos comandos, para que tudo dentro só seja aplicado se o endereço corresponder. As b
ramificações para o final do script para evitar anexar outra string para um Coincidindo b
.
Abordagem diferente sem ramificação:
sed '/f/s/$/foo/;s/^[^f]*b[^f]*$/&bar/'
Como exercício, você mesmo pode descobrir isso com algum sed
conhecimento, usando man sed
se necessário.
Responder2
Se você deseja adicionar a mesma string de texto no final da linha para ambos os cenários (caracteres a serem procurados: 'X' 'Y'), você pode fazer isso da seguinte maneira:
sed -e 's/[XY].*/&__ADDEDTEXT__/' yourfile
Por outro lado, se você quiser textos separados colocados no final das linhas dependendo do caractere, você pode fazer:
sed -e '
/X/s/$/__TEXT1__/; t
/Y/s/$/__TEXT2__/
' yourfile
Onde usamos o t
comando (ler como teste) para detectar se o s///
comando anterior foi bem-sucedido e pular para o final do código sed na linha atual. Além disso, observe a sintaxe: /regex/s/// => se uma linha compreender o regex, execute a substituição na linha.
Responder3
Perl também é uma ferramenta útil que pode fazer tudo facilmente de uma só vez.
Assim, com o exemplo do @Philippos, um programa Perl ficaria assim (parte da sintaxe é opcional e foi adicionada para esclarecimento):
perl -pe '(m/f/&&s/$/foo/)||(m/b/&&s/$/bar/)' file
Isso lê file
e gera o resultado. Você também pode "editar" o arquivo no local usando -pi -e
em vez de -pe
( -i
significa "no local"), então:
perl -pi -e '(m/f/&&s/$/foo/)||(m/b/&&s/$/bar/)' file
Provavelmente também há uma maneira de fazer isso, awk
embora o teste inicial tenha falhado (não sou tão proficiente em AWK), com Ruby (que parece quase o mesmo, envie-me um ping se quiser exemplos) e pode ser divertido em puro Bash.