Extração de dados de um arquivo de texto usando o bash

4

Estou procurando um script bash. Em um arquivo de texto eu tenho dados como:

+------+------
| Id   | User | 
+------+------+
| 8192 | root | 
| 8194 | root |
| 8202 | root |
| 8245 | root | 
| 8434 | root |  
| 8754 | root | 
| 8761 | root | 
| 8762 | root | 
| 8764 | root | 
| 8771 | root | 
+------+------+

Eu quero extrair os dados da seguinte forma:

  

8192,8194,8202,8245,8434,8754,8761,8762,8764

Quer dizer, eu preciso primeiro campo contendo números, mas não o último. E todos os números extraídos devem ser separados por vírgula ( , ).

Alguém poderia me ajudar a conseguir isso?

    
por Ten-Coin 24.02.2014 / 16:27

5 respostas

6

Você não precisa de um script para uma coisa tão simples. Você pode usar awk :

    
awk ' ~ "^[0-9][0-9]*$" { print  }' file.txt | head -n -1 | awk '{print}' ORS=',' | sed 's/,$/\n/'

Algumas explicações:

  • awk ' ~ "^[0-9][0-9]*$" { print }' file.txt - imprima a partir do file.txt apenas os campos que são números.
  • head -n -1 - remove a última linha / último número.
  • awk '{print}' ORS=',' - concatena todas as linhas em uma única linha, cada número separado por , .
  • sed 's/,$/\n/' - substitua a última , por um caractere de nova linha.

Ou mais curto:

awk ' ~ "^[0-9][0-9]*$" { print  }' ORS=',' file.txt | sed 's/,[0-9]*,$/\n/'
    
por Radu Rădeanu 24.02.2014 / 17:22
4

O caminho mais curto que posso encontrar:

echo 'sed 's/[^0-9]//g' your_file' | sed 's/ /,/g'

O resultado é:

8192,8194,8202,8245,8434,8754,8761,8762,8764,8771

[^0-9] - significa tudo menos numéricos

s/[^0-9]//g - remove tudo, exceto os numerais

Substitua your_file pelo caminho para o seu arquivo

Para você, finalmente, tarefa, com o comando kill . Tenha cuidado ao usar esta linha, isso matará todos os PIDs na lista :

for pid in 'sed 's/[^0-9]//g' your_file | grep -v '^$''; do kill -9 $pid;done

Antes de executar a linha anterior, você pode querer executar esta linha:

for pid in 'sed 's/[^0-9]//g' your_file | grep -v '^$''; do echo "kill -9 $pid";done

Ele mostrará algo assim:

kill -9 8192
kill -9 8194
kill -9 8202
kill -9 8245
kill -9 8434
kill -9 8754
kill -9 8761
kill -9 8762
kill -9 8764
kill -9 8771

Boa sorte!

    
por c0rp 24.02.2014 / 18:03
4

Aqui está um folheto para o seu propósito,

sed 's/[^0-9]//g' file.txt| xargs | sed 's/ /,/g'

ou

sed 's/[+|IdUserroot\-]*//g' file.txt | xargs | sed 's/ /,/g'

Saída:

8192,8194,8202,8245,8434,8754,8761,8762,8764,8771

Explicação

man sed

s/regexp/replacement/
          Attempt  to  match  regexp  against the pattern space.  If successful, replace that
          portion matched with replacement.  The replacement may contain the special  charac‐
          ter  & to refer to that portion of the pattern space which matched, and the special
          escapes  through  to refer to the corresponding matching sub-expressions in the
          regexp.

g     Copy/append hold space to pattern space.

Expressão regular [Wikipedia]

[^ ]    Matches a single character that is not contained within the brackets.
For example, [^abc] matches any character other than "a", "b", or "c". [^0-9]
matches any single character that is not a number from "0" to "9".

Por isso, usando sed , substituí tudo por espaço. Próximo xargs coloque-os em uma linha separada por espaço,

$ sed 's/[^0-9]//g' file.txt| xargs
8192 8194 8202 8245 8434 8754 8761 8762 8764 8771

Na última etapa, substituí todos os espaços por , usando sed

    
por souravc 24.02.2014 / 18:47
1

em que o texto está em um arquivo input no mesmo diretório e o resultado é dado em output file.

cat ./input | sed -e 's/+------+------+//g' | sed -e 's/| Id   | User |//g' | sed -e 's/ | root |//g' | tr -d "\n" | sed -e 's/| /,/g' | sed -e 's/ ,/,/g' | sed -e 's/ ,/,/g' > output

Quando fiz o seu exemplo, recebi:

+------+------,8192,8194,8202,8245,8434,8754,8761,8762,8764,8771

Isso pode acontecer porque a linha superior do seu exemplo estava com falta de + - pode haver alguns outros erros ...

Então, acho que você só precisa adicionar sudo /mysql_rms/bin/mysqladmin -S /mysql_rms/var/mysql_rms.sock -p kill no começo

Ou, no que esperamos, uma leve melhora no que Radu sugeriu (também com base na entrada acima):

cat ./input | sed 's/[+-]*//g' | sed 's/ | root |//g' | tr -d "\n" | sed 's/| /,/g' | sed 's/ ,/,/g' | sed 's/ ,/,/g' | sed 's/^,//' | sed 's/,[0-9]* $/\n/' | sed 's/Id//g' | sed 's/,User,,//g' | sed 's/ //g' > output

Então, com base em suas perguntas e respostas aqui , você deve ser capaz de executar:

sudo /mysql_rms/bin/mysqladmin -S /mysql_rms/var/mysql_rms.sock -p kill $(cat ./output)

embora você possa querer verificar se é o comando certo com este primeiro:

echo "sudo /mysql_rms/bin/mysqladmin -S /mysql_rms/var/mysql_rms.sock -p kill $(cat ./output)"
    
por Wilf 24.02.2014 / 17:25
0

Acho que isso é o que você precisava. Algumas outras respostas não conseguiram remover a última parte.

sed -n 's/.*\([0-9]\{4\}\).*//p' file | sed ':a;N;$!ba;s/\n/,/g; s/\(.*\),\(.*\)$//g'

Um pequeno exemplo,

$ (echo '| Id   | User |'; echo '| 8192 | root |'; echo '| 8194 | root |'; echo '| 8771 | root |') | sed -n 's+.*\([0-9]\{4\}\).*++p' | sed ':a;N;$!ba;s/\n/,/g; s/\(.*\),\(.*\)$//g'
8192,8194
    
por Avinash Raj 16.05.2014 / 18:47

Tags