Obtendo um erro ao executar o awk a partir de um script

0

Eu tenho um arquivo some.txt

-rwxrw-r-- 1 ivamshky ivamshky    152 Apr  2 00:42 12.sh~
-rw-rw-r-- 1 ivamshky ivamshky     58 Apr  6 19:03 a.c
-rw-rw-r-- 1 ivamshky ivamshky     98 Apr  1 20:27 all.sh
-rwxrwxr-x 1 ivamshky ivamshky   8509 Apr  6 19:04 a.out
-rw-rw-r-- 1 ivamshky ivamshky     46 Apr  6 19:07 a.py
-rw-rw-r-- 1 ivamshky ivamshky    399 Apr 18 00:37 attendance.csv
-rw-rw-r-- 1 ivamshky ivamshky    341 Apr 20 01:08 attendance.sh
-rw-rw-r-- 1 ivamshky ivamshky      0 Apr 19 16:21 awk
-rw-rw-r-- 1 ivamshky ivamshky    212 Apr 20 01:41 awktest.sh

Agora, eu quero que, se um nome de arquivo no diretório atual estiver presente no arquivo acima, uma nova coloumn seja adicionada àquela linha que tenha "FOUND". por exemplo: se o awktest.sh estiver presente no pwd. então a saída sai para ser:

-rw-rw-r-- 1 ivamshky ivamshky    212 Apr 20 01:41 awktest.sh   FOUND

Eu já escrevi este script (com sua ajuda, obrigado)

 #!/bin/bash
for fn in *
do
    n=$( awk -v fn="$fn" '$0 ~ fn { print NR }' some.txt )
    awk -v n="$n" 'NR==n { $(NF+1)="Found" }1' some.txt >some.out
done

mas não há nenhuma nova coloumn adicionada no arquivo de saída (existem alguns arquivos em pwd que estão presentes em algum.txt

    
por Shivam 21.04.2015 / 20:31

4 respostas

0

Muito fácil, pode ser feito com sed

#!/bin/bash
unset pattern
for fn in *
do
    pattern=${pattern:+${pattern}\|}$f
done
sed -i "/$pattern/s/$/ Found/" some.txt
    
por 21.04.2015 / 21:58
1

O código é muito complicado. Por exemplo

>>  list=$(ls -l | awk 'NR > 1 { print $9;}')
>>  for fn in $list 

Por que você faz ls -l mas depois extrai $9 (o nome do arquivo - mas note que isso só funciona se nenhum espaço em branco for parte do nome do arquivo); em vez de apenas

for fn in *

Em seguida, você faz alguns grep para números de linha e awk para extração de campo

>>  n='grep -n "$fn" some.txt | awk -F":" '{ print $1;}''

mas por que não simplesmente deixar awk fazer a correspondência

n=$( awk -v fn="$fn" '$0 ~ fn { print NR }' some.txt )

E finalmente, em vez de alternar entre shell e awk, citando

>>  awk -F" " 'NR=='"$n"'{OFS=" "; $(NF+1)="Found";}1' some.txt>some.out

passa a variável como parâmetro, como em

awk -v n="$n" 'NR==n { $(NF+1)="Found" } 1'


Agora, juntando essas peças:

for fn in *
do
    n=$( awk -v fn="$fn" '$0 ~ fn { print NR }' some.txt )
    awk -v n="$n" 'NR==n { $(NF+1)="Found" } 1' some.txt >some.out
    mv some.out some.txt
done

Não tenho certeza se isso é exatamente o que você quer, mas é um código mais claro e deve ter menos problemas, pelo menos. Agora com esta reestruturação parece que você pode fazer tudo isso também em apenas um awk instance, parece. (Mas deixo isso como exercício para o leitor.)

    
por 21.04.2015 / 21:24
0
!/bin/bash
list=$(ls -l | awk 'NR > 1 { print $9;}')
for fn in list 
do
echo $fn
    n='grep -n "$fn" some.txt | awk -F":" '{ print $1;}'' # change this
    awk -F" " 'NR=='"$n"'{OFS=" "; $(NF+1)="Found";}1' some.txt>some.out
    mv some.out some.txt
done



!/bin/bash
list=$(ls -l | awk 'NR > 1 { print $9;}')
for fn in list; do # also decided to clean this up
    echo $fn
    n=$(grep -n "$fn" some.txt | awk -F":" '{ print $1;}') # to this
    awk -F" " 'NR=='"$n"'{OFS=" "; $(NF+1)="Found";}1' some.txt>some.out # also, what is this line supposed to do? There is usually a better way to do something that have to run a mv command to overwrite
    mv some.out some.txt
done

Pode haver outra coisa, mas ainda não tomei meu café.

link

    
por 21.04.2015 / 21:17
0

Problemas no seu script:

  • SC2006 - Use $ (..) em vez de legacy '..'.
  • SC2012 - Use a localização em vez de ls para lidar melhor com nomes de arquivos não alfanuméricos.
  • SC1035 - Você está perdendo um espaço necessário após o!

    1  !/bin/bash
        ^––SC1035 You are missing a required space after the !.
    2  list=$(ls -l | awk 'NR > 1 { print $9;}')
              ^––SC2012 Use find instead of ls to better handle non-alphanumeric filenames.
    3  for fn in $list 
    4  do
    5  
    6      n='grep -n "$fn" some.txt | awk -F":" '{ print $1;}''
             ^––SC2006 Use $(..) instead of legacy '..'.
    7      awk -F" " 'NR=='"$n"'{OFS=" "; $(NF+1)="Found";}1' some.txt>some.out
    8      mv some.out some.txt
    9  done
    

Fonte

    
por 21.04.2015 / 21:42