Манипулирование строками в Bash - PullRequest
1 голос
/ 23 мая 2010

Я новичок в Bash и выполняю некоторые манипуляции со строками.

У меня есть следующий файл среди других файлов в моем каталоге:

jdk-6u20-solaris-i586.sh

Я делаю следующее, чтобы получить jdk-6u20 в моем скрипте:

myvar=`ls -la | awk '{print $9}' | egrep "i586" | cut -c1-8`
echo $myvar

, но теперь я хочу преобразовать jdk-6u20 в jdk1.6.0_20.Кажется, я не могу понять, как это сделать.

Это должно быть как можно более общим.Например, если бы у меня был jdk-6u25, я мог бы преобразовать его таким же образом в jdk1.6.0_25 и т. Д. И т. Д.

Есть предложения?

Ответы [ 7 ]

2 голосов
/ 23 мая 2010

В зависимости от того, насколько именно он вам нужен, и от того, насколько стандартными будут ваши входные данные, вы, вероятно, можете использовать AWK для всего. Используя FS="regexp" для указания разделителей полей, вы можете разбить исходную строку по любым токенам, которые имеют наибольший смысл, и собрать их вместе в любом порядке, используя printf.

Например, предполагая, что и тире, и буква 'u' используются только для разделения полей:

myvar="jdk-6u20-solaris-i586.sh"
echo $myvar | awk 'BEGIN {FS="[-u]"}; {printf "%s1.%s.0_%s",$1,$2,$3}'

Аромат по вкусу.

1 голос
/ 23 мая 2010

Использование только Bash:

for file in jdk*i586*
do
    file="${file%*-solaris*}"
    file="${file/-/1.}"
    file="${file/u/.0_}"
    do_something_with "$file"
done
0 голосов
/ 23 мая 2010

Вам нужен awk, там есть артефакт переключателя -l на ls. Для замены шаблонов в строках текста sed - давний чемпион:

ls | sed -n '/^jdk/s/jdk-\([0-9][0-9]*\)u\([0-9][0-9]*\)$/jdk1.\1.0_\2/p'

Это было написано в "старой школе" sed, которая должна иметь большую переносимость между платформами. Выражение говорит:

  • не печатать строки, если они не совпадают -n
  • в строках, начинающихся с 'jdk' do:
  • в строке, содержащей только «jdk-IntegerAuIntegerB»
    • изменить его на "jdk.1.IntegerA.0_IntegerB"
    • и распечатайте

Ваш образец становится еще проще:

myvar=`echo *solaris-i586.sh | sed 's/-solaris-i586\.sh//'`
0 голосов
/ 23 мая 2010

Вы можете попробовать этот фрагмент:

for fname in *; do
    newname=`echo "$fname" | sed 's,^jdk-\([0-9]\)u\([0-9][0-9]*\)-.*$,jdk1.\1.0_\2,'`
    if [ "$fname" != "$newname" ]; then
        echo "old $fname, new $newname"
    fi
done
0 голосов
/ 23 мая 2010

garph0 имеет хорошую идею с sed; Вы могли бы сделать

myvar=`ls jdk*i586.sh | sed 's/jdk-\([0-9]\)u\([0-9]\+\).\+$/jdk1.\1.0_\2/'`
0 голосов
/ 23 мая 2010
awk 'if(match($9,"i586")){gsub("jdk-6u20","jdk1.6.0_20");print $9;}'

if (match ()) заменяет бит egrep, если вы хотите его использовать.Вы также можете использовать substr ($ 9,1,8) вместо cut.

0 голосов
/ 23 мая 2010

я думаю, что

sed
- это команда для вас
...