Как извлечь определенные элементы из имени файла?

export PATH=$(echo -n "$PATH" | awk -v RS=':' '(!a[$0]++){if(b++)printf(RS);printf($0)}')

Сохраняется только первое вхождение и поддерживается относительный порядок.

7
14.07.2017, 19:01
6 ответов

Вы можете сделать это интерактивно, используяGNU sed:

$ sed 's/^\([0-9]\{4\}\)-\([0-9]\{2\}\)-\([0-9]\{2\}.*\)/\1\2\3/g' stuff.txt

Для нескольких файлов (, если они находятся в одном каталоге и нет других рассматриваемых файлов в каталоге):

for file in *
do
    if [ -f "$file" ]
    then
          sed 's/^\([0-9]\{4\}\)-\([0-9]\{2\}\)-\([0-9]\{2\}\).*/\1\2\3/g' "$file"
    fi
done
3
27.01.2020, 20:13

Попробуйте заменить шаблон:

${parameter/pattern/string}
Параметр

— базовое имя файла. узор — тире. В этом /-заменить шаблон глобально. строка пуста, так как вы хотите удалить тире.

mv "${f}" "${f//-/}"

Внимание :У меня не получалось, чтобы это работало с пробелами в расширении.

1
27.01.2020, 20:13

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

for f in *
do 
  [[ $f =~ ^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])(.*) ]] && 
  yourvar="${BASH_REMATCH[1]}${BASH_REMATCH[2]}${BASH_REMATCH[3]}"
done

При этом используется способность bash [[использовать сопоставление регулярных выражений для помещения фрагментов даты в массив BASH _REMATCH.

5
27.01.2020, 20:13

Использование расширения параметра

$ touch 2014-11-19.8.ext 2014-11-26.1.ext
$ for f in *.ext; do d="${f:0:4}${f:5:2}${f:8:2}"; echo "$d"; done
20141119
20141126
  • ${f:0:4}означает 4 символа, начиная с индекса 0, а f— имя переменной
  • замените echo "$d"на ваш код
9
27.01.2020, 20:13

Вот zshспособ сделать это без циклов:

autoload -U zmv
zmv -n '([0-9](#c4))-([0-9](#c2))-([0-9](#c2))(*)' '$1$2$3$4'
  • [0-9](#c4)означает любую цифру, повторенную 4 раза
  • $1-$2относится к ранее использовавшейся скобке
  • -nпредотвращает выполнение (только печатает ), снимите этот флаг, если вы довольны результатом

Поскольку zshзаботится о подстановке всех угловых регистров, (пробелы, специальные символы и т. д. )должны учитываться автоматически.

2
27.01.2020, 20:13

Если вы используете GNU Coreutils, у вас есть:

$ date --date=2014-11-13 +"%Y%m%d"
20141113

Однако:

$ date --date=2014-11-130ABCJUNK +"%Y%m%d"
date: invalid date ‘2014-11-130ABCJUNK’

Таким образом, задача намного проще :извлечь первые десять символов каждого YYYY-MM-DDetcимени файла, чтобы получить дату отдельно, а затем перейти к dateдля переформатирования.

Но если мы используем GNU Coreutils, мы можем пропустить команду date, потому что touchимеет точно такую ​​же опцию --date=STRING.

for file in * ; do
  date=${file%${file##??????????}} # chop all but first ten
  touch --date=$date -- "$file"
done

Но почему это десятисимвольное отсечение переносимым способом POSIX, когда мы полагаемся на touchиз GNU Coreutils?

for file in * ; do
  date=${file:0:10}
  touch --date=$date -- "$file"
done
2
27.01.2020, 20:13

Теги

Похожие вопросы