Найдите второй экземпляр слова в файле и переименуйте файл

Я регистрирую, который система генерирует с универсальным именем файла. Я хочу иметь скрипт, который я могу запустить, какие сканирования эти файлы для второго экземпляра слова ProcID (после того, как слово ProcID является числом) и затем переименовывает файл с номером ProcID. В настоящее время у меня есть следующее:

FILEPATH; awk -F '[:)]' '/ProcID./{printf "mv %s %s.txt\n", FILENAME, $2 | "/bin/sh"; nextfile}' O*.TXT

Например, сценарий сканирует файлы и находит второй экземпляр (ProcID:0000014778) и затем это переименовывает файл с этим Идентификационным номером Proc.

Сценарий выше находок только первая инстанция, и поэтому файлы переименовываются, прежде чем система закончила производить в файл.

3
задан 30 January 2017 в 17:51

2 ответа

Сценарий ниже переименовывает все файлы в каталоге к идентификатору во второй найденной строке, начиная с ProcID::

1. Переименование к идентификатору во второй соответствующей строке (буквально; никакое расширение)

enter image description here

#!/usr/bin/env python3
import shutil
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    file = os.path.join(dr, f)
    try:
        # only rename if the second instance exists
        new = [s for s in open(file).read().split() if s.startswith("(ProcID:")][1]
    except (IndexError, IsADirectoryError):
        pass
    else:
        # rename the file
        shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()[:-1]))

Использовать

  1. Скопируйте сценарий в пустой файл, сохраните его как rename_files.py
  2. выполните его с каталогом как аргумент:

    python3 /path/to/rename_files.py /path/to/directory_with_files
    

Примечания

  • Сценарий принимает (точный) формат: ProcID:0000014778
  • Сценарий не переименует файлы, если не будет никакого второго экземпляра ProcID (или ни один вообще)

2. Только переименуйте .txt файлы и сохраните расширение

... Затем используйте версию ниже, она только переименует .txt файлы и сохраняют расширение в переименованном файле. Использование является точно тем же.

#!/usr/bin/env python3
import shutil
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    file = os.path.join(dr, f)
    try:
        # only rename is the second instance exists
        new = [s for s in open(file).read().split() if all([
            s.startswith("(ProcID:"), f.endswith(".txt")
            ])][1]
    except (IndexError, IsADirectoryError):
        pass
    else:
        shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()[:-1]+".txt"))

Что делает сценарий

  • это перечисляет файлы в каталоге:

    for f in os.listdir(dr)
    
  • перечисляет строки в файле, начиная с ProcID:

    new = [s for s in open(file).read().split() if s.startswith("(ProcID:")][1]
    

    Окончание [1] извлекает второе возникновение строк, начиная с ProcID: ([0] первый),

  • разделения идентификатора:

    new.split(":")[-1].strip()
    
  • и переименовывает файл, с помощью идентификатора:

    shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()[:-1]))
    

Править

Версия Python2 сценария 1. OP, оказывается, имеет установленный python2, который требует IOError вместо IsADirectoryError предотвратить ошибки в случае, если сценарий сталкивается с каталогом вместо файла.

#!/usr/bin/env python
import shutil
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    file = os.path.join(dr, f)
    try:
        # only rename if the second instance exists
        new = [s for s in open(file).read().split() if s.startswith("(ProcID:")][1]
    except (IndexError, IOError):
        pass
    else:
        # rename the file
        shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()[:-1]))

... и для того, чтобы быть завершенным, python2 версия второго сценария:

#!/usr/bin/env python
import shutil
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    file = os.path.join(dr, f)
    try:
        # only rename is the second instance exists
        new = [s for s in open(file).read().split() if all([
            s.startswith("(ProcID:"), f.endswith(".txt")
            ])][1]
    except (IndexError, IOError):
        pass
    else:
        shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()+".txt"))
5
ответ дан 1 December 2019 в 13:23

Ваш исходный сценарий был видом завершения, и это может быть отредактировано для подсчета экземпляров через if оператор и переменная счетчика:

FILEPATH; awk -F '[:)]' '/ProcID./{ count++; if(count == 2 ){ printf "mv %s %s.txt\n", FILENAME, $2 | "/bin/sh"; nextfile}}' O*.TXT

В случае, если Вы ищете альтернативное решение, Вы могли использовать этот сценарий Perl:

#!/usr/bin/env perl
use strict;
use warnings;

my $cnt=0;
open(my $fh,'<',$ARGV[0]) or die "open failed";
my $new_name;
while ( my $line = <$fh> ){
    $cnt+=1 if $line =~ /ProcID/;
    if($cnt==2){
        chomp $line;
        my @words = split(/[:)]/,$line); 
        $new_name = $words[1] . ".TXT";
        last;
    }
}
if (defined $new_name){
   rename $ARGV[0], $new_name;
}
close($fh)

Образец выполняется:

$ ls
0000014777.TXT  rename_by_procid.pl*

$ ./rename_by_procid.pl 0000014777.TXT                                                                                                

$ ls
0000014778.TXT  rename_by_procid.pl*
2
ответ дан 1 December 2019 в 13:23

Другие вопросы по тегам:

Похожие вопросы: