Задать вопрос
serii81
@serii81
Я люблю phр...

Конвертировать px в rem с помощью bash скрипта?

Всем привет.
Я уже написал скрипт, только он конвертирует в rem, только когда на одной строке одно значение с rem.
Например,
margin: 30px;
Когда
padding: 30px 20px 10px;

Конвертирует только первое значение.

#!/bin/bash
#
css_file="$1"

# Iterate through each line of the CSS file
while IFS= read -r line; do
  if [[ $line == *"border"* || $line == *"max-width"* ]]; then
    continue
  else
    # Use regular expressions to find pixel values (e.g., "10px", "20px", etc.)
    px_values=$(echo "$line" | grep -oE "[0-9]+px")
    echo "'px_values:' $px_values"

    # Iterate through each found pixel value
    for px_value in $px_values; do
      # Extract the numeric value from the pixel value
      numeric_value=$(echo "$px_value" | grep -oE "[0-9]+")

      # Convert the pixel value to rem and divide by 10
      rem_value=$(awk "BEGIN { printf \"%.2f\", $numeric_value / 10 }")

      # Replace the pixel value with the calculated rem value
      new_line=$(echo "$line" | sed "s/$px_value/${rem_value}rem/g")
      # sed -i "s/$line/$new_line/" $css_file
    done

    # Print the modified line
    # echo "$line"
  fi
done < "$css_file"


Проблема вот тут
EnBho6k.png

За ранее благодарен за помощь.
  • Вопрос задан
  • 82 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 2
saboteur_kiev
@saboteur_kiev Куратор тега bash
software engineer
Вы немного запутались с $line, $new_line
#!/bin/bash
css_file="$1"

while read -r line; do
  if [[ $line == *"border"* || $line == *"max-width"* ]]; then
    echo "$line"
    continue
  else
    # Use regular expressions to find pixel values (e.g., "10px", "20px", etc.)
    px_values=$(echo "$line" | grep -oE "[0-9]+px")
    new_line="$line"

    # Iterate through each found pixel value
    for px_value in $px_values; do
      # Extract the numeric value from the pixel value
      numeric_value=$(echo "$px_value" | grep -oE "[0-9]+")

      # Convert the pixel value to rem and divide by 10
      rem_value=$(awk "BEGIN { printf \"%.2f\", $numeric_value / 10 }")

      # Replace the pixel value with the calculated rem value
      new_line=$(echo "$new_line" | sed "s/$px_value/${rem_value}rem/g")
      # sed -i "s/$line/$new_line/" $css_file
    done
    # Print the modified line
    echo "$new_line"
  fi
done < "$css_file"
Ответ написан
erge
@erge
Примус починяю
зачем это делать на bash с включением grep, sed и awk, когда все можно сделать на одном awk:

awk -F: '
/\{|\}|border|max-width|^$/ { print $0 }
!/\{|\}|border|max-width|^$/ {
  split( substr($2, 1, length($2)-1) , a," ");
  res = "";
  for (i in a) {
    ind = match(a[i], /[0-9]+px/)
    if (ind != 0) {
      a[i] = sprintf ("%.2frem", a[i]/10);
    }
    res=a[i] " " res;
  }
  res = substr(res, 1, length(res)-1);
  print $1 ": " res ";"
}
' some.css


см. пример на awk.js.org

UPDATE:
заметил что значения перемешиваются (могут перемешиваться когда их 4 и более), это происходит ввиду того что массивы в awk ассоциативные и поэтому при переборе через for in они могут случайно перемешаться.
Arrays in awk are different—they are associative. This means that each array is a collection of pairs—an index and its corresponding array element value...
The pairs are shown in jumbled order because their order is irrelevant.

см. 8.1.1 Introduction to Arrays

переписал на перебор индексов и немного "оптимизировал", убрал форматирование %.2f т.к. при делении на 10 оно не нужно...
awk -F: '{
if ($0 ~ /\{|\}|border|max-width|^$/ ) { print $0 }
else {
  res = "";
  split( substr($2, 1, length($2)-1) , a, " ");
  for (i=1; i<= length(a);i++) res = res " " ((match(a[i], /[0-9]+px/) != 0)? a[i]/10"rem" : a[i]);
  print $1 ": " res";"
}
}' some.css
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@AUser0
Чем больше знаю, тем лучше понимаю, как мало знаю.
Тщательнее надо...
grep -oE "([0-9]+px(\s+|;|$))+"
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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