2013-04-22 2 views
0

Хорошо, у меня есть много файлов, все из которых содержат номер версии v1 или v2. И я хочу, чтобы соответствовать имена файлов в другие файлы, которые составлены в качестве второго файла, как это: train.v1_GENENAME_ID.debruijn.txt (это то, что я хочу)переименование файла (взять 1 часть имени файла и перенести его в «начало» имени файла)

Первый файл, состоящий, как это: поезд. GENENAME_ID_v1.debruijn.txt

И поэтому v1 должен перемещаться перед GENENAME. Все идентификаторы версий одинаковы. А именно v1 или v2

позволяет сказать, что у меня есть файл с именем: 'train.Glis2_1757.2_v1_deBruijn.txt' и я хочу, чтобы преобразовать его в этом 'train.v1_Glis2_1757.2_deBruijn.txt'

Есть ли простой способ взять v1 из первого файла и поместите его как во 2 файла ?

Я думал о объединении grep с выражением if. Но до сих пор не удалось заставить его работать.

Любые советы и подсказки.

+1

В соответствии с тем, какой шаблон представляет собой сценарий, который должен знать, что двигаться и где? – 2013-04-22 14:13:54

+0

Первым шагом было бы сделать его абстрактной проблемой, поэтому она программируется. Как вы можете написать его в терминах «XXX.v1_YYY ...»? Независимо от того, как они, отправьте свои тесты, чтобы у нас появилась идея. – fedorqui

+1

@fedorqui я изменил вопрос, может быть, его более ясно сейчас. –

ответ

1

Вот один, используя для цикла и использование sed для преобразования имен файлов

for f in *.txt; 
do 
    nf=$(echo $f | sed -r 's/([^.]+\.)([^.]+\.)([0-9])_([^_]+)(.*)/\1\4_\2\3\5/') 
    echo mv $f $nf 
done 

Если вы удовлетворены результатами, вы можете удалить echo и пусть переименование произойдет

согласно вашему запросу здесь представляет собой аннотированную версию, поясняющую, как различные части извлекаются и перегруппированы, чтобы соответствовать желаемому результату.

echo "train.Glis2_1757.2_v1_deBruijn.txt" | sed -r 
's/([^.]+\.) # match all non-dot characters (+ meaning one or more) followed by a dot and store in group 1 (train.) 
    ([^.]+\.) # match all non-dot characters followed by a dot and store in group 2 (Glis2_1757.) 
    ([0-9]) # match a single digit and store in group 3 (2) 
    _   
    ([^_]+) # match all non-underscore characters and store in group 4 (v1) 
    (.*)  # match all that follow . is a wildcard char in regex and * is for zero or more (_deBruijn.txt) 
/\1\4_\2\3\5/' # rearranging the matches to get desired output 
+1

Некоторые цитаты ('' ') были бы приятными, чтобы избежать сюрпризов. –

+0

@shyam спасибо за ваш ответ, но мое знание регулярных выражений - это низкое, чтобы полностью понять это. Не могли бы вы объяснить еще кое-что? –

+0

@shyam спасибо за объяснение, я просто прочитал его. Приятно и ясно для меня сейчас. Для очков я приму свой ответ! –

2

Используйте rename распространяется с Perl:

rename 's/(train.)(.*_)(v[0-9].)(deBruijn.txt)/$1$3$2$4/' * 

В некоторых системах это называется 'РЕН' или 'Pren'.

+0

Очень хороший! Просто тестирование - может ли это выражение использоваться с sed? 'echo" train.Glis2_1757.2_v1_deBruijn.txt "| sed 's/(train.) (. * _) (v [0-9].) (deBruijn.txt)/$ 1 $ 3 $ 2 $ 4 /' 'не работает для меня. – fedorqui

+0

Я думаю, что '$ 1' должно быть' \ 1', и вам также понадобится флаг '-r' – shyam

+0

. Не следует ли вам сбежать из' .', то есть заменить его на '\ .'? –

1

Вы можете сделать это в оболочке с parameter expansion, в частности, суффикс и удаление префикса:

FN=train.Glis2_1757.2_v1_deBruijn.txt 
STRIPPED=${FN%_deBruijn.txt}      # "train.Glis2_1757.2_v1" 
GENEVERS=${STRIPPED#train.}      # "Glis2_1757.2_v1" 
VERSION=${GENEVERS##*_}       # "v1" 
GENENAME=${GENEVERS%_v[12]}      # "Glis2_1757.2" 

NEWFN=train.${VERSION}_${GENENAME}_deBruijn.txt # "train.v1_Glis2_1757.2_deBruijn.txt" 

mv $FN $NEWFN 

Вам не придется пройти через все явные шаги именовании выше, но я думаю, что это понятнее. Кроме того, этот метод можно экстраполировать, чтобы иметь произвольные префиксы (кроме «train») и суффиксы (кроме «_deBruijn.txt»), предполагающие, что вы можете представлять их с нотной оболочкой.

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