Analisa a saída ls usando sed para obter a localização do arquivo de arquivos com nomes específicos

1

Para começar, eu sei que esse caminho não é o certo, como frequentemente mencionado por que não devo analisar a saída de ls , mas é uma parte do meu projeto universitário (então eu poderia usar sed e awk).

Eu tenho que encontrar arquivos cujos nomes começam com uma determinada string. Eu olhei com a listagem do diretório atual usando ls :

ls -LR1

que me dá o exemplo de saída:

.:
bin
etc
games
include
lib
man
sbin
share
src

./bin:
apt
gnome-help
highlight
mint-sha256sum
pastebin
search
szukaj
yelp

./etc:

./games:

./include:

./lib:
python2.7
python3.5

./lib/python2.7:
dist-packages
site-packages

./lib/python2.7/dist-packages:

./lib/python2.7/site-packages:

./lib/python3.5:
dist-packages

./lib/python3.5/dist-packages:

./man:

./sbin:

./share:
ca-certificates
emacs
fonts
man
sgml
xml

./share/ca-certificates:

./share/emacs:
site-lisp

./share/emacs/site-lisp:

./share/fonts:

./share/man:

./share/sgml:
declaration
dtd
entities
misc
stylesheet

./share/sgml/declaration:

./share/sgml/dtd:

./share/sgml/entities:

./share/sgml/misc:

./share/sgml/stylesheet:

./share/xml:
declaration
entities
misc
schema

./share/xml/declaration:

./share/xml/entities:

./share/xml/misc:

./share/xml/schema:

./src:

Agora, quero usar sed ou possivelmente awk para obter arquivos com nomes que começam com determinada string, digamos 'Do' . Eu gostaria de conseguir algo assim:

  1. sed (ou awk ?) analisa cada linha e procura pela linha que começa com 'Do'
  2. Se houver uma correspondência, move-se para a linha anterior e procura por. (que é um indicador de caminho relativo), se não houver correspondência, pula para a linha antes e assim por diante
  3. Imprime a linha como caminho relativo: .path/filename

É possível até conseguir? Obrigado pela sua ajuda!

    
por Dandry 14.10.2016 / 21:48

2 respostas

2

Como exemplo, vamos considerar esses arquivos:

$ ls -LR1
.:
a

./a:
b

./a/b:
bad
Do_good

Agora, vamos encontrar o arquivo que você deseja:

$ ls -LR1 | awk '/^\.\//{sub(/:$/, "/", $0); dir=$0} /^Do/{print dir $0}'
./a/b/Do_good

Como funciona:

  • /^\.\//{sub(/:$/, "/", $0); dir=$0}

    Sempre que encontramos uma linha que começa com ./ , substituímos a localização : por / e atualizamos a variável dir

  • /^Do/{print dir $0}

    Sempre que encontramos uma linha que inicia Do , imprimimos a variável dir seguida por esta linha.

Limitação: Como você sabe, a saída de ls deve ser legível e analisada, não é confiável. Este código serve apenas para demonstrar o uso de awk . Não deve ser usado para nada sério.

Método preferido

Como curinga apontou, find é a ferramenta certa para essa tarefa:

$ find . -name 'Do*'
./a/b/Do_good
    
por 14.10.2016 / 22:20
2

Com sed , você usaria o espaço de espera para armazenar o caminho do último diretório visto:

sed -n '
  /^\..*:$/{
    h;d
  }
  /^Do/{
    G
    s|\(.*\)\n\(.*\):|/|p
  }'
    
por 14.10.2016 / 22:48

Tags