Como iterar arquivos usando awk, bash ou ruby?

0

Eu tenho três arquivos de remarcação na minha máquina:

$ ls | grep md
bar.md
baz.md
foo.md

Cada arquivo tem o conteúdo fornecido:

$ cat *md
i am bar
i am baz
i am foo

Como exemplo, eu gostaria de "fazer um loop sobre todos os arquivos que correspondam ao padrão *.md e imprimir o padrão: file_name: file_contents ".

Eu me sinto mais confortável trabalhando com rubi. Mas eu gostaria de praticar meus bash for-loops e também desenvolver meu habilidades do awk .

O Ruby é o mais fácil para mim:

#!/usr/bin/env ruby
# iterate over all markdown files in current directory

Dir.glob('*.md').each do |some_file|
  puts "#{some_file}: #{File.read(some_file)}"
end

saída:

$ ./iterate_over_files.rb
bar.md: i am bar
baz.md: i am baz
foo.md: i am foo

E seguindo o recurso bash vinculado, criei o seguinte loop:

#!/usr/bin/env bash
# iterate over all markdown files in current directory

for some_file in *.md
do
  echo $some_file: 'cat $some_file'
done

que fornece o mesmo resultado:

$ diff <(./iterate_over_files.sh) <(./iterate_over_files.rb) # no difference

Eu sei de assistir a uma apresentação por Brian Kernaghan e por revisar is slides que essa é uma ótima oportunidade de usar o awk porque segue o padrão:

for each file
  for each input line 
    for each pattern
      if the pattern matches input line
        do the action
  • Como aproveito esse padrão usando o awk e faço iteração em todos os arquivos de marcação e imprimo um resultado formatado?
por mbigras 28.03.2017 / 23:06

2 respostas

3

De acordo com o manual bash , você deve usar $(< FILE) em vez de $(cat FILE) . Mas não há necessidade de usar a substituição de comandos:

for some_file in *.md
do
  echo -n "$some_file: "
  cat $some_file
done

Como você já sabe da substituição do processo, também pode fazer algo como:

for some_file in *.md
do
  cat <(echo -n "$some_file: ") $some_file
done
    
por 29.03.2017 / 08:04
3

Como sobre isso, processa cada arquivo e gera o nome do arquivo usando a variável FILENAME.

$ awk '{print FILENAME":",$0}' *.md
bar.md: i am bar
baz.md: i am baz
foo.md: i am foo
$

Ou este, um pouco mais difícil para os olhos, mas apenas define $ 0 para o nome do arquivo seguido pelo conteúdo do arquivo. A ação padrão para awk é imprimir $ 0, por isso não precisa de print .

$ awk '$0=FILENAME": "$0' *.md
bar.md: i am bar
baz.md: i am baz
foo.md: i am foo
$

Outra abordagem. Em vez de usar FILENAME, usa o array de argumentos ARGV.

$ awk '$0=ARGV[++z]": "$0' *.md
bar.md: i am bar
baz.md: i am baz
foo.md: i am foo
$
    
por 28.03.2017 / 23:21

Tags