Exclua os últimos n caracteres das linhas do arquivo

Exclua os últimos n caracteres das linhas do arquivo

Estou usando um terminal Mac (bash) e tenho um arquivo chamado data_list.txtque contém nas seguintes linhas:

aaabbbccc_7777.txt 
nnhhaa_8888.txt 
ayquabay_9999.txt 
ayqynbnbn_1122.txt 
ooppaa_3454.txt

Como posso remover os últimos 8 caracteres de cada linha?

Saída esperada de data_list.txt:

aaabbbccc_ 
nnhhaa_ 
ayquabay_ 
ayqynbnbn_ 
ooppaa_

Obrigado por qualquer ajuda

Responder1

Se quiser excluir os últimos 8 caracteres, ou todos eles, se houver menos de 8, você pode fazer:

sed "s/.\{0,8\}$//; /^$/d" data_list.txt

Não há necessidade de regex estendido. Isso limpará tantos caracteres quanto possível, mas não mais que 8. Se isso deixar uma linha vazia, ela será removida da saída.

Se precisar limpar qualquer espaço em branco à direita (sem incluí-lo nos 8 caracteres), você pode fazer:

sed "s/.\{0,8\}[[:space:]]*$//" data_list.txt

Só posso adivinhar qual é a condição real para o que deve ser removido no final (por exemplo, tudo após o sublinhado ou um número + a extensão), mas se você quiser remover a extensão do arquivo e quaisquer dígitos antes dele:

sed "s/[[:digit:]]*\..*$//" data_list.txt

Outras respostas já mostraram como remover tudo após o sublinhado, então não vou repetir.

Responder2

Para sua entrada exata (todas as linhas em suas extremidades têm espaço em branco, exceto a última linha), você pode usar isto (suponho que você queira se livrar de 'after _ part':

sed 's/........ *$//' data_list.txt

Para se livrar de qualquer coisa após o último caractere 'sublinhado', use este:

sed 's/\(.*_\).*$/\1/' data_list.txt

Também funcionará em linhas que possuem vários caracteres 'sublinhados', porque sed é 'ganancioso'. Embora eu não saiba se isso funcionará no MacOS, pelo menos será útil para usuários do Linux sed que o mecanismo de pesquisa do Google chegará aqui ...

Responder3

Aqui está uma awksolução tão rápida quanto a sedabordagem do frippe, usando um arquivo de exemplo com 100.000 linhas:

time awk '{print substr($0, 1, length($0)-8)}' 100k.txt

real    0m4.110s
user    0m0.142s
sys     0m0.422s

time sed "s/.\{0,8\}$//; /^$/d" 100k.txt

real    0m4.043s
user    0m1.558s
sys     0m0.345s

Substitua 8por qualquer número. A principal diferença aqui é que awkimprimirá uma nova linha se o comprimento do corte exceder o comprimento da linha, mas sednão o fará.

Responder4

Usando Raku (anteriormente conhecido como Perl_6)

raku -ne '.trim-trailing.chop(8).put;'

OU

raku -pe '.=trim-trailing; .=chop(8);'

Entrada de amostra:

wxxyyyzzzz_1234.txt
aaabbbccc_7777.txt 
nnhhaa_8888.txt 
ayquabay_9999.txt 
ayqynbnbn_1122.txt 
ooppaa_3454.txt

Saída de amostra:

wxxyyyzzzz_
aaabbbccc_
nnhhaa_
ayquabay_
ayqynbnbn_
ooppaa_

Observe que ambas as respostas acima usam a trim-trailingrotina de Raku para se livrar dos espaços em branco à direita. Sinta-se à vontade para excluir trim-trailinge/ou ajustar o número de caracteres chop-ped da extremidade direita da string.

https://docs.raku.org/routine/chop
https://raku.org

informação relacionada