1

У меня много данных с такими именами файлов:

20110.bil
20111.bil
20112.bil
...
2011150.bil
2011151.bil
2011152.bil

Шаблон имени файла выше:

year+(0-152)

0-152 означают с 1 августа по 31 декабря.

Я хочу изменить это имя файла на

20110801.bil
20110802.bil
20110803.bil
............
............
20111229.bil
20111230.bil
20111231.bil

Шаблон имени файла, который я хочу это:

year+month+day.

Как мне решить мою проблему?

2 ответа2

1

Как насчет этого решения Bash?

#!/bin/bash

shopt -s nullglob extglob
for file in +([[:digit:]]).bil; do
    file_noext=${file%.bil}
    year=${file_noext::4}
    day=${file_noext:4}
    [[ -z $day ]] || ((0<=day && day<=152 && ${#year}==4)) || { echo "Error with file $file"; continue; }
    newname=$(date -d "$year-08-01 + $day days" '+%Y%m%d.bil')
    echo mv -nv "$file" "$newname"
done
  • Это зациклит все файлы вида X.bil где X - число (состоит только из цифр).
  • Для каждого файла и после удаления расширения .bil мы извлекаем первые четыре символа (year) и получаем оставшиеся цифры в переменной day .
  • Затем есть строка, которая проверяет, все ли в порядке (day не пуст, между 0 и 152, а year действительно имеет 4 символа).
  • После этого мы используем утилиту date (надеюсь, у вас есть умная date такая как моя, которая может выполнять арифметику с датами, здесь добавьте дни к определенной).
  • Наконец, мы выполняем переименование (ну, я оставил echo перед mv , чтобы команда только отображалась, а не выполнялась; удалите echo если вас это устраивает).

Тестовое задание. Я назвал этот скрипт banana (с удаленным echo ), и я chmod +x banana . Затем:

$ mkdir scratch
$ cd scratch
$ touch 2011{0,42,100,151}.bil
$ ls
20110.bil  2011100.bil  2011151.bil  201142.bil
$ ./banana
`20110.bil' -> `20110801.bil'
`2011100.bil' -> `20111109.bil'
`2011151.bil' -> `20111230.bil'
`201142.bil' -> `20110912.bil'
$ ls
20110801.bil  20110912.bil  20111109.bil  20111230.bil

Выглядит хорошо!

0

Следующий скрипт сделает это за вас:

 #!/bin/bash


 > out.txt
 while read line; do
    mytmp=$(echo $line | sed 's/.bil$//' | sed 's/^2011//' )
    echo $mytmp
    if [ $mytmp -lt 31 ]; then
            MONTH=08
            DAY=$(( $mytmp + 1))
    elif  [ $mytmp -lt 61 ]; then
            MONTH=09
            DAY=$(( $mytmp - 30 ))
    elif  [ $mytmp -lt 92 ]; then
            MONTH=10
            DAY=$(( $mytmp - 60 ))
    elif  [ $mytmp -lt 122 ]; then
            MONTH=11
            DAY=$(( $mytmp - 91 ))
    elif  [ $mytmp -lt 153 ]; then
            MONTH=12
            DAY=$(( $mytmp -121 ))
    fi
    echo "2011$MONTH$DAY.bil" >> out.txt

 done < data

Он работает следующим образом: он читает строку с именем data, строка за строкой, и помещает вывод в файл с именем out.txt (измените его так, как вам больше подходит). Первая строка очищает выходной файл, а затем считывает файл данных, удаляя строку начального 2011 года и конечного .bil. Осталось день кодирования. Затем, в зависимости от кодирования дня, он определяет соответствующий месяц и день и восстанавливает строку, предварительно ожидая 2011 года, добавляя .bil и помещая окончательную строку в файл output.txt.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .