2014-02-11 4 views
6

У меня есть следующие файлы в следующем формате:Баш удаления части имени файла

$ ls CombinedReports_LLL-*'('*.csv 
CombinedReports_LLL-20140211144020(Untitled_1).csv 
CombinedReports_LLL-20140211144020(Untitled_11).csv 
CombinedReports_LLL-20140211144020(Untitled_110).csv 
CombinedReports_LLL-20140211144020(Untitled_111).csv 
CombinedReports_LLL-20140211144020(Untitled_12).csv 
CombinedReports_LLL-20140211144020(Untitled_13).csv 
CombinedReports_LLL-20140211144020(Untitled_14).csv 
CombinedReports_LLL-20140211144020(Untitled_15).csv 
CombinedReports_LLL-20140211144020(Untitled_16).csv 
CombinedReports_LLL-20140211144020(Untitled_17).csv 
CombinedReports_LLL-20140211144020(Untitled_18).csv 
CombinedReports_LLL-20140211144020(Untitled_19).csv 

Я хотел бы эту часть удалена:
20140211144020 (это метка времени отчеты были проведены таким образом, это будет меняться)

и в конечном итоге что-то вроде:

CombinedReports_LLL-(Untitled_1).csv 
CombinedReports_LLL-(Untitled_11).csv 
CombinedReports_LLL-(Untitled_110).csv 
CombinedReports_LLL-(Untitled_111).csv 
CombinedReports_LLL-(Untitled_12).csv 
CombinedReports_LLL-(Untitled_13).csv 
CombinedReports_LLL-(Untitled_14).csv 
CombinedReports_LLL-(Untitled_15).csv 
CombinedReports_LLL-(Untitled_16).csv 
CombinedReports_LLL-(Untitled_17).csv 
CombinedReports_LLL-(Untitled_18).csv 
CombinedReports_LLL-(Untitled_19).csv 

Я думал просто вдоль линий mv команда, возможно, что-то вроде этого:

$ ls CombinedReports_LLL-*'('*.csv 

но, возможно, sed команды или другой будет лучше

+0

Возможный дубликат [удаление части файла из нескольких файлов] (http://stackoverflow.com/questions/12174947/removing-a-part-of-filename-of-a-bunch-of-files). – Joel

ответ

10

rename является частью perl пакета. Он переименовывает файлы в соответствии с регулярными выражениями в стиле perl. Чтобы удалить даты из ваших имен файлов:

rename 's/[0-9]{14}//' CombinedReports_LLL-*.csv 

Если rename не доступен, может быть использован sed + shell:

for fname in Combined*.csv ; do mv "$fname" "$(echo "$fname" | sed -r 's/[0-9]{14}//')" ; done 

Вышеуказанные петли над каждым из ваших файлов. Для каждого файла он выполняет команду mv: mv "$fname" "$(echo "$fname" | sed -r 's/[0-9]{14}//')", где в этом случае sed может использовать то же регулярное выражение, что и команда rename. s/[0-9]{14}// сообщает sed, чтобы найти 14 цифр подряд и заменить их пустой строкой.

+0

Нет необходимости в sed - современная оболочка может выполнять собственные замены. –

+0

@CharlesDuffy (1) Я вообще стремлюсь к совместимости с Dash не только потому, что он намного быстрее, чем bash, но также потому, что простая оболочка гораздо более широко поддерживается. (2), в то время как Bash может выполнять примитивные подстановки, regex's sed в конечном счете намного более мощный. – John1024

+0

PE, доступные в POSIX sh и, таким образом, тире, достаточны для этой конкретной работы. Конечно, вы не можете выполнять замены, но вы ** можете ** фильтровать для начала и окончания строк и комбинировать их. Что касается утверждения о том, что regexes sed более мощные - у bash есть встроенная поддержка регулярных выражений (см. 'BASH_REMATCH') и имеет режим, в котором его глобусы сравнимы по мощности с BRE (см.' Extglob'). –

0

Вы можете использовать утилиту rename для этого. Он использует синтаксис так же, как sed для изменения имен файлов. Следующий пример (из переименования человеко-страницы) показан, как удалить концевую расширение «.bak» из списка резервных копий файлов в локальном каталоге:

rename 's/\.bak$//' *.bak 
+0

не имеют команды 'rename' в моей версии cygwin в минуту. Любым другим путем? – HattrickNZ

5

без использования других инструментов, таких как rename или sed и приклеить строго bash в одиночку:

for f in CombinedReports_LLL-*.csv 
do 
    newName=${f/LLL-*\(/LLL-(} 
    mv -i "$f" "$newName" 
done 
+0

+1. Но почему бы не поместить все в команду mv напрямую?' mv -i "$ f" "$ {f/LLL - * \ (/ LLL - (}" ' – BMW

+2

Почему? Для ясности, конечно, посмотрите на сердца и умы коллег-программистов и угадайте, какое решение будет лучше всего понято. Я предположил, что, кстати, OP поставил свой вопрос, что он лучше понимает это с помощью имени переменной говорящего типа 'newName ' – Alfe

+0

получил это. ОП. – BMW

0
for f in CombinedReports_LLL-* ; do 
    b=${f:0:20}${f:34:500} 
    mv "$f" "$b" 
done 

Вы можете попробовать построчно на оболочке:

f="CombinedReports_LLL-20140211144020(Untitled_11).csv" 
b=${f:0:20}${f:34:500} 
echo $b 
+1

Будем надеяться, что все числа (метки времени) имеют одинаковую ширину. И все же, любой, кто читает этот код, должен будет угадать, откуда взялись эти константы ('0',' 20', '34' и' 500') и что они означают. Конечно, не исключено, но это не самый ясный способ. – Alfe

0

Я использую рекомендации, приведенные в верхнем ответе, и поместили следующую строку в сценарий оболочки:

ls *.nii | xargs rename 's/[f_]{2}//' f_0*.nii 

В терминале эта линия работает отлично, но в моем скрипте она не будет выполняться и читается * как буквальная часть имени файла.

Смежные вопросы