Como excluir o restante de cada linha após um determinado padrão ou string em um arquivo?

21

Suponha que eu tenha uma lista de URLs em um arquivo de texto:

google.com/funny
unix.stackexchange.com/questions
isuckatunix.com/ireallydo

Quero excluir tudo o que vem depois de '.com'.

Resultados esperados:

google.com
unix.stackexchange.com
isuckatunix.com

eu tentei

sed 's/.com*//' file.txt 

mas também foi excluído .com.

Koshur
fonte
Existe um motivo específico pelo qual você deseja pesquisar .comapenas em vez de remover tudo depois e incluindo o primeiro /caractere? E se você tivesse um URL como en.wikipedia.org/wiki/Ubuntuna sua lista?
Byte Commander

Respostas:

17

Para excluir explicitamente tudo o que vem depois de ".com", basta ajustar sua solução sed existente para substituir ".com (qualquer coisa)" por ".com":

sed 's/\.com.*/.com/' file.txt

Ajustei seu regex para escapar do primeiro período; caso contrário, seria semelhante a "thisiscommon.com/something".

Observe que você pode ancorar ainda mais o padrão ".com" com uma barra à direita, para não aparar acidentalmente algo como "sub.com.domain.com/foo":

sed 's/\.com\/.*/.com/' file.txt
Jeff Schaller
fonte
9

Você pode usar awko separador de campos ( -F) da seguinte maneira:

$ cat file
google.com/funny
unix.stackexchange.com/questions
isuckatunix.com/ireallydo

$ cat file | awk -F '\\.com' '{print $1".com"}'
google.com
unix.stackexchange.com
isuckatunix.com

Explicação:

NAME
       awk - pattern scanning and processing language

-F fs
       --field-separator fs
              Use fs for the input field separator (the value of the FS predefined variable).

Como você deseja excluir todas as coisas depois .com, -F '.com'separa a linha .come print $1fornece a saída apenas a parte anterior .com. Assim, $1".com"adiciona .come fornece a saída esperada.

Pandya
fonte
Por que não apenas /como FS e entrar no primeiro campo?
precisa saber é
11
@ Pandand: Isso falhou com string comoacomercial.com/asdsad
cuonglm
@cuonglm Obrigado por apontar. Resposta melhorada
Pandya
4

A melhor ferramenta para edição in-loco de arquivos não interativa é ex.

ex -sc '%s/\(\.com\).*/\1/ | x' file.txt

Se você usou vie já digitou um comando que começa com dois pontos, :você usou um comando ex. É claro que muitos dos comandos mais avançados ou "sofisticados" que você pode executar dessa maneira são extensões do Vim (por exemplo :bufdo) e não estão definidos nas especificaçõesex do POSIX , mas essas especificações permitem um nível verdadeiramente surpreendente de poder e flexibilidade em sistemas não visuais. edição de texto (interativa ou automatizada).

O comando acima possui várias partes.

-sativa o modo silencioso para se preparar expara o uso em lote. (Suprimir as mensagens de saída et. Al.)

-cespecifica o comando a ser executado assim que o arquivo ( file.txtneste caso) for aberto em um buffer.

%é um especificador de endereço equivalente a 1,$— significa que o seguinte comando é aplicado a todas as linhas do buffer.

sé o comando substituto com o qual você provavelmente já está familiarizado. É comumente usado vie possui recursos essencialmente idênticos ao scomando desed , embora alguns dos recursos avançados do regex possam variar de acordo com a implementação. Nesse caso, de ".com" até o final da linha é substituído por apenas ".com".

A barra vertical separa comandos seqüenciais a serem executados. Em muitas eximplementações, você também pode usar uma -copção adicional , como:

ex -sc '%s/\(\.com\).*/\1/' -c x file.txt

No entanto, isso não é requerido pelo POSIX.

O xcomando é encerrado após a gravação de quaisquer alterações no arquivo. Diferente do wqque significa "gravar e sair", xsomente grava no arquivo se o buffer tiver sido editado. Portanto, se o seu arquivo não for alterado, o registro de data e hora será preservado.

Curinga
fonte
11
+1 para usar ex
Jeff Schaller
11
Não edita no local. Pelo menos, não é mais do que sedo falso Gnu -i. Ele lê / grava em buffers no disco. Veja você mesmo com ex -ro preservecomando.
mikeserv
@mikeserv Qual é o preservecomando?
Mateen Ulhaq 18/09
2

Maneira python muito rápida, simples e suja:

#!/usr/bin/env python
import sys
with open( sys.argv[1]  ) as file:
    for line in file:
        print line.split("/")[0]

Amostra de execução

skolodya@ubuntu:$ chmod +x removeStrings.py                                   

skolodya@ubuntu:$ ./removeStrings.py strings.txt                              
google.com
unix.stackexchange.com
isuckatunix.com


skolodya@ubuntu:$ cat strings.txt                                             
google.com/funny
unix.stackexchange.com/questions
isuckatunix.com/ireallydo
Sergiy Kolodyazhnyy
fonte
2
Posso saber o motivo do voto negativo?
Sergiy Kolodyazhnyy
3
Funciona, mas não se importa .com, apenas remove tudo que começa com o primeiro /da linha. (que na minha opinião é mesmo a melhor abordagem!)
Byte Commander
11
@ByteCommander exatamente certo! Se o nome do domínio for .net, em outras abordagens, a parte que vem depois do domínio e da extensão não seria excluída, portanto, é mais seguro usá-lo /como separador.
Sergiy Kolodyazhnyy
+1 para respostas e comentários que me fazem sentir como se estivesse no AskUbuntu.com: D
WinEunuuchs2Unix