Заполните числовые значения в имени файла трехзначным значением с помощью sed - PullRequest
2 голосов
/ 27 марта 2012

Я передаю имя файла в мой bash-скрипт и очищаю имя с помощью sed.Вот несколько примеров файлов:

Test 01.txt
Test v2 01.txt

Я хотел бы получить обратно:

Test 001.txt
Test v002 001.txt

Вот мой сценарий

#!/bin/bash

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for f in $@
do

j=`basename "$f" ".???"`
BASENAME=`basename "$f" ".???"`
DIRNAME=`dirname "$f"`

j=`echo $j |sed -e 's/\///g'`
j=`echo $j |sed -e 's/_/ /g'`
j=`echo $j |sed -e 's/^\.//'`
j=`echo $j |sed -e 's/\[[^()]*\]//g'`
j=`echo $j |sed -e 's/([^()]*)//g'`
j=`echo $j |sed -e 's/#//g'`
j=`echo $j |sed -e 's/+/\ /g'`
j=`echo $j |sed -e 's/\.\././g'`
j=`echo $j |sed -e 's/\&/and/g'`
j=`echo $j |sed -e 's/\ -/-/g'`
j=`echo $j |sed -e 's/-\ /-/g'`
j=`echo $j |sed -e 's/-{2,}/-/g'`
j=`echo $j |sed -r -e 's/\d+/sprintf("%03d",$&)/e'`
j=`echo $j |sed -e 's/\.\././g'`
j=`echo $j |sed -e "s/\'//g"`
j=`echo $j |sed -r -e 's/ {2,}/ /g'`
j=`echo $j |sed -e 's/\ \././g'`

if [ "$BASENAME" != "$j" ]; then
  mv -v "$f" "$DIRNAME"/"$j"
fi

done

Вот проблемная строка

j=`echo $j |sed -r -e 's/\d+/sprintf("%03d",$&)/e'`

Регулярное выражение будет работать с переименованием, но не с sed.

Ответы [ 3 ]

2 голосов
/ 28 марта 2012

Это может сработать для вас (GNU sed):

sed  -r 's/[0-9]+/$(printf "%03d" &)/g;s/.*/echo "&"/e' file
Test 001.txt
Test v002 001.txt
2 голосов
/ 28 марта 2012

вместо

sed -r -e 's/\d+/sprintf("%03d",$&)/e'

использование

perl -pe 's/\d+/sprintf("%03d",$&)/ge'
1 голос
/ 28 марта 2012

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

Это почти так же просто, и не требует шага очистки позже, чтобы переместить заключительные строки и"'" символ вверх и вниз по списку, как показано ниже, для отладки (в качестве альтернативного решения).

j=$(
  echo "$j" \
  | sed '
    s/\///g
    s/_/ /g
    s/^\.//
    s/\[[^()]*\]//g
    s/([^()]*)//g
    s/#//g
    s/+/\ /g
    s/\.\././g
    s/\&/and/g
    s/\ -/-/g
    s/-\ /-/g
    s/-{2,}/-/g
    s/\.\././g
    s/'"'"'//g
    s/ {2,}/ /g
    s/\ \././g
' \
| awk '/[0-9]/{
   match( $0,/[0-9][0-9]*/ )
   begin=substr($0,1,RSTART); end=substr($0,RSTART+RLENGTH,length($0))
   num=substr($0,RSTART,RSTART+RLENGTH)
   printf("%s%03d%s", begin,num+0, end)
  }'
)

Редактировать Может быть возможно удвоить тройку на экранированных одинарных кавычкахто есть \\' или \\\', но я иду с проверенным и верным s/'"'"'//g.

Если вы не используете оригинальную оболочку Bourne в Solaris, AIX, HP или других старых версиях Unixen, присоединяйтесь к 1990-м годам ;-) и используйте конструкцию $( ...) для подстановки команд.Обратные кавычки устарели, по крайней мере, в «Новом языке программирования Kornshell», опубликованном в 1995 году.

Надеюсь, это поможет.

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