Pergunta
Eu acho AWK realmente útil. Aqui está um um forro eu juntos para manipular dados.
ls | awk '{ print "awk " "'"'"'" " {print $1,$2,$3} " "'"'"'" " " $1 ".old_ext > " $1 ".new_ext" }' > file.csh
Eu usei esse AWK para fazer um arquivo script que iria renomear alguns arquivos e só imprimir colunas seletivos. Alguém sabe uma maneira melhor de fazer isso? O que você melhores AWK forros ou manipulações inteligentes?
Solução
O AWK livro está cheio de grandes exemplos. Eles costumavam ser recolhidos para download Kernighan da página (404s agora).
Outras dicas
Você pode encontrar vários forros agradável um aqui .
Eu uso este:
df -m | awk '{p+=$3}; END {print p}'
Para totalizar todo o espaço em disco usado em um sistema através de sistemas de arquivos.
Muitos anos atrás eu escrevi um script cauda em awk:
#!/usr/bin/awk -f
BEGIN {
lines=10
}
{
high = NR % lines + 1
a[high] = $0
}
END {
for (i = 0; i < lines; i++) {
n = (i + high) % lines + 1
if (n in a) {
print a[n]
}
}
}
É bobagem, eu sei, mas é o que awk faz com você. É apenas muito divertido jogar com ele.
Henry Spencer escreveu uma boa implementação de nroff em awk. Ele o chamou de "AWF". Ele também alegou que, se Larry Wall soubesse o quão poderoso awk foi, ele não teria necessidade de inventar perl.
Aqui está um par de awks que eu costumava usar regularmente ... Note que você pode usar $ 1, $ 2, etc para sair da coluna que deseja. Então, para manipular um monte de arquivos, por exemplo, aqui é um comando estúpido você pode usar em vez de mv ...
ls -1 *.mp3 | awk '{printf("mv %s newDir/%s\n",$1,$1)}' | /bin/sh
Ou se você está olhando para um conjunto de processos talvez ...
ps -ef | grep -v username | awk '{printf("kill -9 %s\n",$2)}' | /bin/sh
Pretty trivial, mas você pode ver como é que iria levá-lo completamente maneiras. =) A maioria das coisas que eu costumava fazer você pode usar xargs para, mas hey, quem precisa deles nova fangled comandos?
Eu uso este script muito para editar PATH e caminho-como variáveis ??de ambiente. Uso:
export PATH=$(clnpath /new/bin:/other/bin:$PATH /old/bin:/other/old/bin)
Este comando adiciona / new / bin e / outro / bin na frente do PATH, remove ambos / / bin de idade e / other / / bin velho de PATH (se presente - sem erro se ausente), e remove entradas de diretório duplicados no caminho.
: "@(#)$Id: clnpath.sh,v 1.6 1999/06/08 23:34:07 jleffler Exp $"
#
# Print minimal version of $PATH, possibly removing some items
case $# in
0) chop=""; path=${PATH:?};;
1) chop=""; path=$1;;
2) chop=$2; path=$1;;
*) echo "Usage: `basename $0 .sh` [$PATH [remove:list]]" >&2
exit 1;;
esac
# Beware of the quotes in the assignment to chop!
echo "$path" |
${AWK:-awk} -F: '#
BEGIN { # Sort out which path components to omit
chop="'"$chop"'";
if (chop != "") nr = split(chop, remove); else nr = 0;
for (i = 1; i <= nr; i++)
omit[remove[i]] = 1;
}
{
for (i = 1; i <= NF; i++)
{
x=$i;
if (x == "") x = ".";
if (omit[x] == 0 && path[x]++ == 0)
{
output = output pad x;
pad = ":";
}
}
print output;
}'
memória Conde usado por httpd
ps -ylC httpd | awk '/[0-9]/ {SUM += $8} END {print SUM/1024}'
ou qualquer outro processo, substituindo httpd. Dividindo por 1024 para obter uma saída em MB.
I conseguiu construir um emulador comando árvore do DOS para UNIX (encontrar + awk):
find . -type d -print 2>/dev/null|awk '{for (i=1;i< NF;i++)printf("%"length($i)"s","|");gsub(/[^\/]*\//,"--",$0);print $NF}' FS='/'
linhas de impressão entre dois padrões:
awk '/END/{flag=0}flag;/START/{flag=1}' inputFile
explicação detalhada: http://nixtip.wordpress.com/2010/10/12/print-lines-between-two-patterns-the-awk-way/
Um par de favoritos, essencialmente independentes uns dos outros. Leia como 2 sugestões diferentes, sem ligação.
Identificar números das colunas facilmente
:
Para aqueles que usam awk com frequência, como eu faço para análise de log no trabalho, muitas vezes eu encontro-me a necessidade de descobrir o que os números das colunas são para um arquivo. Então, se eu estou analisando, por exemplo, acessar arquivos Apache (algumas amostras pode ser encontrada aqui ) eu executar o script abaixo contra o arquivo:
NR == 1 {
for (i = 1 ; i <= NF ; i++)
{
print i "\t" $i
}
}
NR > 1 {
exit
}
Eu normalmente chamam de "cn.awk", para n'umbers 'c'olumn'. Criativa, hein? De qualquer forma, os olhares de saída como:
1 64.242.88.10
2 -
3 -
4 [07/Mar/2004:16:05:49
5 -0800]
6 "GET
7 /twiki/bin/edit/Main/Double_bounce_sender?topicparent=Main.ConfigurationVariables
8 HTTP/1.1"
9 401
10 12846
Muito fácil de dizer o que é o quê. Eu costumo apelido isso em meus servidores e tê-lo em todos os lugares.
Referenciando campos por Nome
Agora, suponha que o arquivo tem uma linha de cabeçalho e você preferir usar esses nomes em vez de números de campo. Isso permite que você a fazê-lo:
NR == 1 {
for (i = 1 ; i <= NF ; i++)
{
field[$i] = i
}
}
Agora, suponha que eu tenho essa linha de cabeçalho ...
metric,time,val,location,http_status,http_request
... e eu gostaria de resumir a coluna val
. Em vez de se referir a US $ 3, posso referir a ele pelo nome:
NR > 1 {
SUM += $field["val"]
}
O principal benefício é fazer o script muito mais legível.
Impressão de campos é uma das primeiras coisas mencionadas na maioria dos tutoriais AWK.
awk '{print $1,$3}' file
Menos conhecido, mas igualmente útil é excluindo campos que também é possível:
awk '{$1=$3=""}1' file