2014-09-19 1 views
4

Допустим, у меня есть следующие файлы: 1.html, 2.html и 3.html и я хочу переименовать их 1.html Бака, 2. html-bak и 3.html-bak. Для этого я выполняю следующую команду:Как сократить строку

find . -name '*.html' -print0 | xargs -0 -I {} mv {} {}-bak 

Все в порядке, файлы переименовываются, как ожидалось.

Вопрос в том, как переименовать их обратно в *.html вместо *.html-bak?

Как удалить последние 4 символа из строки?

+2

Вам не нужно 'xargs'; 'найти. -name '* .html' -exec mv '{}' '{} -bak' \; '. – chepner

ответ

7

${file%-*} Чтобы получить требуемое имя файла - Следующий код перебирает все файлы, имена которых оканчиваются html-bak и выполняет переименование, удалив все после последнего тире:

for file in *html-bak 
do 
    echo "mv $file ${file%-*}" # <-- using "echo" for safety. Remove once checked 
done 

${var%-*} вырезает короткий матч * от задней $var. То есть, удаляет до первой черточки - не найден, начиная с правой стороны:

$ file="1.h-tml-bak" 
$ echo ${file%-*} 
1.h-tml 

Вы, конечно, могли бы также использовать длину, чтобы получить все, кроме последних 4-х символов:

$ echo ${file:0:-4} 
1.h-tml 
+2

Я не думаю, что '0' необходимо (' '$ {file :: - 4}" работает для меня). При более ранних отрицательных значениях bash не поддерживаются, но вы можете сделать '' $ {file :: {# file} -4} "'. –

+1

В качестве единственного элемента ответа, '' $ {file: 0: -4} ', также может быть заменен стандартным' $ {file # ????} '. '$ {var: x: y}' полезна, когда 'x' и' y' не являются константами, поскольку нет концепции подсчета в шаблонах. – chepner

+0

Спасибо за оба комментария, я полностью согласен. @chepner Я думаю, вы имеете в виду '$ {file% ????}' (последние 4 символа, а не первые). Мое впечатление, что лучше использовать '$ {file% - *}' для этого конкретного случая, так как он более общий: таким образом мы могли бы удалить все расширенные имена файлов как 'file-bak',' file- резервное копирование "и т. д. Вот почему я добавил '$ {file: 0: -4}' в качестве другого возможного подхода, а не рекомендуемого. – fedorqui

2

Если вы имеют GNU Parallel вы можете запустить:

find . -name '*.html-bak' -print0 | parallel -0 mv {} {.}.html 

Это работает, даже если имена файлов содержат»," и пространство

.

Все новые компьютеры имеют несколько ядер, но большинство программ являются серийными по своей природе и поэтому не будут использовать несколько ядер. Тем не менее, многие задачи чрезвычайно parallelizeable:

  • Выполнить ту же программу на многих файлах
  • Выполнить ту же самую программу для каждой строки в файле
  • Run та же программа для каждого блока в файле

GNU Parallel - это общий параллелизатор и позволяет легко запускать задания параллельно на одном компьютере или на нескольких компьютерах, к которым у вас есть доступ ssh.

Если у вас есть 32 различных заданий, которые вы хотите работать на 4-х процессоров, прямо вперед способ распараллеливания является выполнение 8 заданий на каждом CPU:

Simple scheduling

GNU Parallel вместо порождает новый процесс, когда один заканчивается - поддержание процессоров активным и тем самым экономя время:

GNU Parallel scheduling

Установка

Личная установка не требует доступа root. Это может быть сделано в течение 10 секунд, делая это:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash 

Для других вариантов установки см http://git.savannah.gnu.org/cgit/parallel.git/tree/README

Подробнее

Другие примеры: http://www.gnu.org/software/parallel/man.html

смотреть интро видео: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Прогулка по t он учебник: http://www.gnu.org/software/parallel/parallel_tutorial.html

Зарегистрируйтесь на список адресов электронной почты, чтобы получить поддержку: https://lists.gnu.org/mailman/listinfo/parallel

+0

Это чрезвычайно удивительно и полностью подавлено для этого вопроса. Еще спасибо за публикацию, параллельно - аккуратно! – msarahan