Удаление символов из нескольких имен файлов - PullRequest
1 голос
/ 20 февраля 2020

У меня есть несколько сотен файлов, из которых мне нужно удалить указанные c символы - в этом случае нули в кратных. Мои имена файлов выглядят так:

filename.R10001.out
filename.R10002.out
....
filename.R10010.out
filename.R10011.out

Я хочу заменить все начальные нули перед номерами файлов подчеркиванием, чтобы я получил:

filename.R1_1.out
filename.R1_2.out
....
filename.R1_10.out
filename.R1_11.out

У меня есть попробовал пару других решений, но я не уверен, как это сделать sh, когда число нулей меняется или пишется аналогичная строка несколько раз с разными числами.

for f in ./*; do mv "$f" "${f%R1*1}.out" ; done

Ответы [ 4 ]

2 голосов
/ 20 февраля 2020

Если вы используете Bash, регулярное выражение может изменить имя файла:

#!/usr/bin/env bash

# Enable Bash Extended Globbing
shopt -s extglob

# Iterate files matching the Extended Globbing
for f in ./*.R[[:digit:]]+(0)+([[:digit:]]).out; do
  # If f is a regular file AND matches the RegEx
  if [[ -f "$f" && "$f" =~ (.*\.R[[:digit:]])0*([[:digit:]]+.*) ]]; then
    # Rename the file using RegEx's captured groups
    mv "$f" "${BASH_REMATCH[1]}_${BASH_REMATCH[2]}"
  fi
done
2 голосов
/ 20 февраля 2020

Попробуйте это

for f in ./* ; do
  newname=$(echo "$f" | sed "s/0\{2,10\}/_/g")
  echo mv "$f" "$newname"
done

Объяснение:

L oop все файлы в текущем каталоге, создайте переменную $ newname, заменив 2 или более ( Предположим, до 10 {2,10} ) вхождения 0 с _.
Проверьте это и, если хотите, удалите эхо.

Редактировать после предложения в комментарии

for f in ./* ; do
   newname=$(echo "$f" | sed "s/0\{2,\}/_/g")
   echo mv "$f" "$newname"
done
0 голосов
/ 21 февраля 2020

Вот решение sed only:

$ ls filename.* | sed 's/\(.*R1\)\(0*\)\([0-9].*\)/mv & \1_\3/'  
mv filename.R10001.out filename.R1_1.out
mv filename.R10002.out filename.R1_2.out
mv filename.R10010.out filename.R1_10.out
mv filename.R10011.out filename.R1_11.out

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

$ ls filename.* | sed 's/\(.*R1\)\(0*\)\([0-9].*\)/mv & \1_\3/'   | bash
0 голосов
/ 20 февраля 2020

С помощью инструмента rename на основе Perl:

$ rename -n 's/0+/_/' *.out
'filename.R10001.out' would be renamed to 'filename.R1_1.out'
'filename.R10002.out' would be renamed to 'filename.R1_2.out'
'filename.R10010.out' would be renamed to 'filename.R1_10.out'
'filename.R10011.out' would be renamed to 'filename.R1_11.out'

Если выходные данные выглядят правильно, вы можете удалить параметр -n и фактически переименовать.


В качестве альтернативы, с расширенными глобами (все еще предполагая, что замена первого вхождения нулей - это то, что мы хотим заменить):

for f in ./*.out; do echo mv "$f" "${f/+(0)/_}"; done

Для этого необходимо установить shopt -s extglob. Бросьте echo, когда команды выглядят правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...