2010-12-11 2 views
6

Я запускаю скрипт, который генерировал около 10k файлов в каталоге. Я только что обнаружил, что в скрипте есть ошибка, которая приводит к тому, что некоторые имена файлов имеют возврат каретки (предположительно символ «\ n»).команда sed для исправления имен файлов в каталоге

Я хочу запустить команду sed, чтобы удалить возврат каретки из имен файлов.

Кто-нибудь знает, какие параметры передать sed, чтобы очистить имена файлов описанным образом?

Я бегу Linux (Ubuntu)

ответ

7

Не знаю, как sed сделал бы это, но этот сценарий python должен сделать трюк :.

Это не sed, но я считаю python намного проще в использовании, делая такие вещи, как эти:

#!/usr/bin/env python 

import os 

files = os.listdir('.') 

for file in files: 
    os.rename(file, file.replace('\r', '').replace('\n', '')) 
    print 'Processed ' + file.replace('\r', '').replace('\n', '') 

Он раздевает вхождения как \r и \n из всех имен файлов в заданной директории ,

Чтобы запустить его, сохраните его где-нибудь, cd в целевой каталог (с файлами, подлежащими обработке) и запустите python /path/to/the/file.py.

Кроме того, если вы планируете больше переименовывать партии, рассмотрите Métamorphose. Это действительно хороший и мощный графический интерфейс для этого. И, это бесплатно!

Удачи вам!


На самом деле, попробуйте следующее: cd в каталог, введите в python, а затем просто вставьте в:

exec("import os\nfor file in os.listdir('.'):\n os.rename(file, file.replace('\\r', '').replace('\\n', ''))\n print 'Processed ' + file.replace('\\r', '').replace('\\n', '')") 

Это версия одной строкой предыдущего сценария, и вы не» t сохранить его.


Version 2, с заменой пространства полномочий:

#!/usr/bin/env python 

import os 

for file in os.listdir('.'): 
    os.rename(file, file.replace('\r', '').replace('\n', '').replace(' ', '_') 
    print 'Processed ' + file.replace('\r', '').replace('\n', '') 

И вот один вкладыш:

exec("import os\nfor file in os.listdir('.'):\n os.rename(file, file.replace('\\r', '').replace('\\n', '')replace(' ', '_'))\n print 'Processed ' + file.replace('\\r', '').replace('\\n', '');") 
+0

@blender: спасибо за скрипт. Я запускаю его в порядке, но имена файлов по-прежнему «разбиты» по нескольким строкам. Какой другой персонаж может вызвать это ?. Очевидно, что \\ r и \\ n не являются виновниками здесь :( – skyeagle

+0

Вы уверены, что это не просто упаковка и пробелы? Для меня длинные имена файлов разбиваются по пробелам. Если вы хотите, я могу изменить его, чтобы заменить пробелы с подчеркиваниями.Может быть, это поможет? – Blender

+0

Я также написал сценарий замены пространства. Проверьте это, может быть, это сработает? Никаких других символов, кроме '\ n' и' \ r', вызывают разрывы строк. Это может быть только ваш файловый менеджер ... – Blender

1

EDIT: Если вы действительно хотите его с sed, посмотрите на это:

Что-то вдоль этих линий должны работать аналогично perl ниже:

for i in *; do echo mv "$i" `echo "$i"|sed ':a;N;s/\n//;ta'`; done 

С Perl, попробовать что-то вдоль этих линий:

for i in *; do mv "$i" `echo "$i"|perl -pe 's/\n//g'`; done 

Это будет переименовать все файлы в текущей папке, удалив все символы новой строки из них. Если вам нужно пойти рекурсивно, вы можете использовать find вместо этого - помните об экранировании в этом случае.

+0

Никто не может понять, как это сделать с 'sed';) – Blender

+0

Я отредактировал, чтобы добавить решение' sed' - когда я впервые ответил, я использовал 'perl', поскольку' sed' не является инструментом, подходящим для многострочных редактирование (как вы можете видеть из строки - perl one намного проще следовать). –

+0

Мех, я все еще предпочитаю Python над 'sed' в любой день. С этим гораздо легче работать. – Blender

4

Если нет пробелов в ваших именах файлов, вы можете сделать:

for f in *$'\n'; do mv "$f" $f; done 

Это не сработает, если e newlines встроены, но он будет работать для вывода новых строк.

Если вы должны использовать sed:

for f in *$'\n'; do mv "$f" "$(echo "$f" | sed '/^$/d')"; done 

Использование сценария rename Perl:

rename 's/\n//g' *$'\n' 

или утилиту Util-Линуксом нг:

rename $'\n' '' *$'\n' 

Если персонаж return вместо новой строки, измените значение \n или ^$ - \r в любых местах, где они отображаются выше.

+0

Почему downvote? –

+0

Назад на ноль;) Я не уверен, почему люди просто случайным образом сбрасывают вниз. Вероятно, новички, которые только что получили эту привилегию, хотели получить этот новый значок ... – Blender

+0

@Blender: Спасибо. Один для вас на пути. –

2

Причина, по которой вы не получаете какие-либо чистые ответы sed, состоит в том, что принципиально sed редактирует содержимое файла, а не имена файлов; поэтому ответы, которые используют sed, делают что-то вроде echo filename в pipe (псевдофайл), редактируют это с помощью sed, а затем используйте mv, чтобы превратить это обратно в имя файла.

С sed выходит, вот версия чисто-баш, чтобы добавить к Perl, Python и т.д. сценарии у вас есть до сих пор:

killpattern=$'[\r\n]' # remove both carriage returns and linefeeds 
for f in *; do 
    if [[ "$f" == *$killpattern* ]]; then 
     mv "$f" "${f//$killpattern/}" 
    fi 
done 

... но так как ${var//pattern/replacement} не доступен в простом sh (наряду с [[...]]), вот версия с использованием sh -Только синтаксиса и tr сделать замену символов:

for f in *; do 
    new="$(printf %s "$f" | tr -d "\r\n")" 
    if [ "$f" != "$new" ]; then 
     mv "$f" "$new" 
    fi 
done 
0

на самом деле есть способ использовать СЭД:

carr='\n'          # specify carriage return 
files=($(ls -f))        # array of files in current dir 
for i in ${files[@]} 
do 
    if [[ -n $(echo "$i" | grep $carr) ]]  # filenames with carriage return 
    then 
     mv "$i" "$(echo "$i" | sed 's/\\n//g')" # move! 
    fi 
done 

Это действительно работает.

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