Нужно сгладить каталог, изменив имена файлов.С баш? - PullRequest
2 голосов
/ 31 марта 2011

У меня есть структура каталогов с 50000+ файлов.Имена файлов имеют вид <YYMMDD>-<NNN>.htm.

Структура каталогов:

/<category>/<YYYY>/<MM>/

Например:

./Racing/1998/03/980320-001.htm
./Racing/1998/03/980320-002.htm
...
./General/1999/02/990221-001.htm
./General/1999/02/990221-002.htm
...

Я хочупростой список файлов в форме

<category>-<YYYY>-<MM>-<DD>-<NNN>

Таким образом, выше будет

Racing-1998-03-20-001.htm
Racing-1998-03-20-002.htm
...
General-1999-02-21-001.htm
General-1999-02-21-002.htm

Я (пере) изучаю bash & regex и будуценим несколько советов о том, как это реализовать.

Я знаю, как создать список путей, но не знаю, как применить регулярное выражение для преобразования формы.Я бы использовал find -type f -name "*.htm" | <some goblygook here>

, где <some goblygook here> мог бы использовать xargs ...

Заранее спасибо.

[РЕДАКТИРОВАТЬ 3/30 9:58pm]

Согласно приведенным ниже ответам, я придумал этот сценарий.Я не могу заставить xargs работать:

#!/bin/bash
mkdir ./flat
find -type f -name "*.htm" | \
awk -F'[/]' '
BEGIN{OFS="-"}
{ gsub(/^\.\//,"") ;print "./" $0 " ./flat/" $1,$2, substr($4,3,2),substr($4,5,2),substr($4,8)}
' | \
xargs -p -d "\n" -n 1 cp

Запуск этого дает мне:

$ ./awktest.sh
mkdir: cannot create directory `./flat': File exists
cp ./General/1997/05/970525-002.htm ./flat/General-1997-05-25-002.htm ?...y
cp: missing destination file operand after `./General/1997/05/970525-002.htm ./flat/General-1997-05-25-002.htm'
Try `cp --help' for more information.
^C

Копирование точной команды cp (cp ./General/1997/05/970525-002.htm ./flat/General-1997-05-25-002.htm) из этого вывода и вставка егопрямо в командной строке bash работает нормально.

Я попытался выяснить, как использовать -print0 в команде find, но не смог понять, как заставить awk использовать \0 в качестве ограничителя записи (RS="\0" не будет работать),Я думаю, что проблема связана с переводом строки, но я в растерянности!

Ответы [ 4 ]

3 голосов
/ 31 марта 2011

find -type f -name "*.htm" | sed 's@^./@@g;s@/@-@g' | awk -F'-' '{print $1 "-" $2 "-" $3 "-" substr($4, 5, 2) "-" $5}'

sed & awk очень полезны для манипулирования текстом.

2 голосов
/ 28 октября 2011

Мне пришлось скорректировать принятый ответ, чтобы работать на меня:

find -type f -name "*.png" | awk -F'[/]' 'BEGIN{OFS="_"}{ 
   gsub(/^\.\//,"") 
   source = "source root folder" $1 "/" $2 "/" $3 
   destination = "destination folder" $1 OFS $2 OFS $3
   command = "cp "source" "destination
   system(command)
}'
1 голос
/ 31 марта 2011

Обычно нет необходимости использовать sed, когда присутствует awk.Это еще один ответ, который не требует дополнительного sed процесса

find -type f -name "*.htm" | awk -F'[/]' 'BEGIN{OFS="-"}{ gsub(/^\.\//,"") ;print $1,$2, substr($4,3,2),substr($4,5,2),substr($4,8) }'

Правка, вы можете сделать cp внутри awk

find -type f -name "*.htm" | awk -F'[/]' 'BEGIN{OFS="-"}{ 
   gsub(/^\.\//,"") 
   source = $1 OFS $2 OFS substr($4,3,2) OFS substr($4,5,2) OFS substr($4,8) 
   destination = <create your destination here>
   command = "cp "source" "destination
   system(command)
}'
0 голосов
/ 31 марта 2011

Чтобы скопировать файлы следующим образом:

eval "`find -type f -name "*.htm" |awk -F/ '{print "cp " $0 " " $2 "-" $3 "-" $4 "-" substr($5,5) ";" }'`"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...