export PATH=$(echo -n "$PATH" | awk -v RS=':' '(!a[$0]++){if(b++)printf(RS);printf($0)}')
Сохраняется только первое вхождение и поддерживается относительный порядок.
Вы можете сделать это интерактивно, используя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
Попробуйте заменить шаблон:
${parameter/pattern/string}
Параметр — базовое имя файла. узор — тире. В этом /-заменить шаблон глобально. строка пуста, так как вы хотите удалить тире.
mv "${f}" "${f//-/}"
Внимание :У меня не получалось, чтобы это работало с пробелами в расширении.
Чтобы перебрать каждый файл в текущем каталоге и сравнить их имена файлов с желаемым шаблоном, затем установите переменную, содержащую фрагменты даты
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.
Использование расширения параметра
$ 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"
на ваш код Вот 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
заботится о подстановке всех угловых регистров, (пробелы, специальные символы и т. д. )должны учитываться автоматически.
Если вы используете 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