Modificações linha por linha no Unix

Modificações linha por linha no Unix

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:

  1. Procure um caractere em uma linha de texto (suponha que você esteja usando GREP?)
  2. Se encontrado, adicione algum texto no final dessa linha (usando SED?)
  3. Se não for encontrado, procure outro caractere na mesma linha
  4. Se encontrado, adicione texto no final da linha, caso contrário, não faça nada
  5. LOOP PARA TODAS AS LINHAS DO ARQUIVO

Qualquer indicação seria apreciada.

Responder1

Tudo isso é sedtrabalho, você não precisa de ferramentas extras:

Digamos que você queira adicionar foono final da linha contendo um fe barno 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 fgatilho para a execução da ssubstituição e o b(o {}grupo dos comandos, para que tudo dentro só seja aplicado se o endereço corresponder. As bramificaçõ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 sedconhecimento, usando man sedse 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 tcomando (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ê filee gera o resultado. Você também pode "editar" o arquivo no local usando -pi -eem vez de -pe( -isignifica "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, awkembora 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.

informação relacionada