Como dividir arquivos com prefixo comum no bash

2

Eu tenho um diretório com muitos arquivos com prefixo comum, como gsc*_other.foo , onde * é um caractere que vai de 0 a 9 ou a / b (onde a significa 10 e b para 11 ). Meu objetivo é criar arquivos de texto com o mesmo gsc* por cada um (ou seja, o primeiro arquivo de texto tem todos os gsc0_other.foo , o segundo todos os gsc1_other.foo e assim por diante). Eu só sei que eu preciso de algo como split , mas dividindo sobre um prefixo comum, em vez de um número de linhas ou tamanho dos arquivos. Eu já fiz um script semelhante, para listar arquivos até um número máximo de arquivos:

find ./J0902-405/*.evt -maxdepth 1 -type f -printf '%f\n' | 
  split -l498 -d - files_xselect.list

E eu procurei muitas outras maneiras de alterar esse script de acordo com o que eu preciso (como mais split , xargs , sed ), mas não tenho como ir junto com isso.

    
por Py-ser 30.01.2014 / 03:11

2 respostas

3

Existem muitas maneiras de conseguir isso, basta passar por cima dos diferentes valores que você deseja dividir, por exemplo

for i in {0..9} a b; do
    ls -1 gsc"${i}"* > filelist"${i}".txt
done

Isso será executado com eficiência

ls -1 gsc0* > filelist0.txt
ls -1 gsc1* > filelist1.txt
ls -1 gsc2* > filelist2.txt
...

Observe que, se nenhum arquivo existir, a mensagem de erro será impressa em stderr, ou seja, no terminal, não redirecionada para a lista de arquivos, a lista de arquivos será criada, mas permanecerá vazia.

    
por 30.01.2014 / 03:26
1

Supondo que todos os seus arquivos são do padrão gsc*_* , quero dizer, onde a string entre o gsc e o _ é o que você deseja usar como índice, isso deve funcionar:

find ./J0902-405/*.evt -maxdepth 1 -type f -printf '%f\n' | 
   awk -F'_' '{print $0 > $1"_list.txt"}'

Isso criará arquivos chamados gsc0_list.txt , gsc1_list.txt etc.

O truque é fornecer awk um sublinhado ( _ ) como seu separador de campo ( -F'_' ) para que o primeiro campo ( $1 ) seja gsc0 ou gsc1 ou gsc11 etc. Em seguida, você anexa ( print >> ) a linha atual (o nome do arquivo) a um arquivo chamado "whatever value $1 has"_list.txt .

Um teste:

$ tree
├── foo
│   └── bar
│       ├── gsc0_12630.foo
│       ├── gsc10_14894.foo
│       ├── gsc11_23911.foo
│       ├── gsc1_18215.foo
│       ├── gsc2_14017.foo
│       ├── gsc3_22263.foo
│       ├── gsc4_16461.foo
│       ├── gsc5_29327.foo
│       ├── gsc6_14337.foo
│       ├── gsc7_27295.foo
│       ├── gsc8_7591.foo
│       └── gsc9_31840.foo
├── gsc0_26853.foo
├── gsc10_30741.foo
├── gsc11_27136.foo
├── gsc1_25097.foo
├── gsc2_1446.foo
├── gsc3_7110.foo
├── gsc4_7399.foo
├── gsc5_14557.foo
├── gsc6_21869.foo
├── gsc7_13413.foo
├── gsc8_2952.foo
└── gsc9_20981.foo

$ find . -type f -printf '%f\n' | awk -F'_' '{print $0 > $1"_list.txt"}'
$ ls *txt
gsc0_list.txt   gsc11_list.txt  gsc2_list.txt  gsc4_list.txt  
gsc6_list.txt   gsc8_list.txt   gsc10_list.txt gsc1_list.txt   
gsc3_list.txt  gsc5_list.txt  gsc7_list.txt  gsc9_list.txt
$ cat gsc6_list.txt
gsc6_21869.foo
gsc6_14337.foo

Observe que isso não fornece o caminho do arquivo e você pode facilmente ter nomes duplicados, mas está removendo explicitamente o caminho com o comando find -printf , portanto, suponho que seja o que você deseja fazer.

    
por 30.01.2014 / 05:44