Pegue certos conteúdos de um arquivo

9

Então, eu sei que existem ferramentas para esse problema porque ouvi falar delas, mas não sei o que são.

Eu quero fazer algo como filtrar todos os dados, exceto os nomes de usuário em / etc / passwd.

Por exemplo, eu gostaria de pegar user1, user2 e user3 do arquivo a seguir. Nesse caso, a lógica poderia ser "Pegue o texto até o primeiro ':' em cada linha do arquivo".

user1:x:1:4
user2:x:2:5
user3:x:3:6

A saída seria:

user1
user2
user3
mouche
fonte

Respostas:

19

cutexiste exatamente para esse fim. O -dsinalizador especifica o delimitador e -fespecifica os campos a serem gerados:

cut -d: -f1 /etc/passwd

O argumento para -fpode ser algo como 1,3mostrar o primeiro e o terceiro campos ou 1-3mostrar os três primeiros; também existem sinalizadores -be -cpara ler bytes e caracteres em vez de campos. Se você precisar de algo mais flexível, geralmente awkfará o truque (consulte a resposta de Mateus )

Michael Mrozek
fonte
13

Toda vez que você deseja extrair dados de uma entrada tabular, considere o awk . Está disponível em praticamente todos os sistemas Unix, por isso é um bom hábito:

awk -F':' '{print $1}' /etc/passwd 
  • -F':': define ":" como o delimitador da coluna.
  • '{}': execute esta instrução para cada linha.
  • print $1: imprime a primeira coluna na tela.
Matthew Brannigan
fonte
3
Nota aleatória: awkpega um nome de arquivo, para que você possa pular o cachimbo e simplesmente fazerawk -F: '{print $1}' /etc/passwd
Michael Mrozek
Sempre pareço esquecer que o awk leva um nome de arquivo, sempre o uso em um pipeline ... algo como sed | awk etc ...
Matthew Brannigan
quase tudo que funciona com arquivos usa um nome de arquivo ( tre atsão alguns exemplos das poucas coisas que não funcionam).
Pausado até novo aviso.
3

Aqui está um one-liner Perl:

perl -F/:/ -lane 'print $F[0]' /etc/passwd
Zaid
fonte
1

Abaixo de perl e awk, há uma terceira ferramenta para esses trabalhos, que é sed:

sed 's/:.*//' FILE 

Este é o comando de substituição: substitute from colon:, seguido por um ponto, que é um curinga para caracteres de qualquer tipo, de qualquer contagem (*), sem nada.

É (ubstitute) / FROM / TO / 'com TO vazio, o que significa' exclua tudo do primeiro (como sed é por padrão ganancioso) dois pontos (até o final da linha, pois sed funciona bem com linhas inteiras).

Claro que também cuté um bom comando, mas eu diria de uma família diferente.

Usuário desconhecido
fonte
1

No seu exemplo, todos os três nomes têm o mesmo comprimento. Nesses casos - o que pode acontecer, mas não tão provável com / etc / passwd - você também pode usar o colrm:

echo "user1:x:1:4
> user2:x:2:5
> user3:x:3:6" | colrm 6
user1
user2
user3

ou, claro

cat FILE | colrm 6 

(um caso raro em useless use of catque não se aplica, porque você não pode colocar um FILE à mão para atuar como parâmetro.)

Usuário desconhecido
fonte
catainda é inútil lá: colrm 6 < FILE.
manatwork
Bem, sim, mas não tão inútil, como na chamada cat foo | grep bar.
desconhecido usuário
1

Apenas para completar, não há necessidade de comandos externos, o shell (Bourne shell ou compatível) pode lidar sozinho:

while IFS=':' read -r needed garbage; do echo "$needed"; done < input_file

Obviamente, essa é provavelmente a mais lenta de todas as soluções possíveis; portanto, para arquivos grandes, escolha outra.

homem a trabalhar
fonte