Как Вы получаете десятичное число из математической операции, включающей переменную?

Я думаю, что главное отличие между использованием регулярного выражения состоит в том, требуют ли они соответствия всей последовательности или нет. В случае , найти и некоторых других команд bash вы должны соответствовать всей последовательности, в то время как в sed , awk , grep и так далее вы должны соответствовать любой части последовательности. Кроме того, они похожи, но, конечно, не идентичны.

Например, при использовании регулярного выражения в операторах case оболочки bash предполагается, что регулярное выражение описывает весь ряд. Т.е. (я использую пример здесь )

case $SERVER in
db-[0-9]+\.host\.com) echo "DB server"
;;
*)echo "Unknown server"
;;
esac

Вы можете видеть, что db- [0-9] + .host.com описывает последовательность, которая начинается с «db-», затем имеет одну или несколько цифр, а затем заканчивается на «. host.com», так что db-1.host.com будет совпадать, в то время как xdb-1.host.com не будет.

Теперь, если вы посмотрите на sed , и написать образец поиска в аналогичном пути

echo "xdb-1.host.com"| sed -nr '/db-[0-9]+\.host\.com/p'

sed , в отличие от case команды, БУДЕТ напечатать строку xdb-1.host.com, потому что он может найти поиск образца INSIDE этого ряда. Итак, идея не в том, чтобы соответствовать всей последовательности, а в том, чтобы найти любое вхождение образца.

В аналогичном пути при использовании команды regexp в find вся последовательность должна совпадать. Например,

find / -regextype sed -regex ".*\.dat"

найдет все файлы с данными расширения. Но если вы попытаетесь выполнить тот же поиск с sed ,

find / | sed -nr '/.*\.dat/'

он будет соответствовать всем файлам, которые содержат последовательность «.dat» в имени файла.

Конечно, существуют некоторые незначительные синтаксические различия. Например, если вы делаете

find / -name "*.dat"

это также своего рода регулярное выражение, где * означает «любое количество произвольных символов», но в строгом смысле regexp вы должны написать. «*,» где «.» означает любой символ, и * означает любое количество символов рода «»., так что вместе означает любое количество любых символов.

-121--217760-

Если вы просто хотите выделить скрытые файлы (и папки), и вас не волнует раскраска всех остальных файлов, то очевидный подход состоит в том, чтобы запустить ls -la | grep -E «^ |\. [^/| '.]. *»

Если вы хотите сохранить другие цвета, то все начинает усложняться, потому что $ LS _ COLORS изначально не поддерживает раскраску скрытых файлов, как это

Я предложил динамически добавлять скрытые файлы текущего каталога к переменной среды $ LS _ COLORS в качестве псевдо-расширения, затем выполнять ls -la и после этого запускать dircolors для сброса исходной цветовой схемы. Очевидно, что возникнет конфликт, если скрытый файл будет иметь то же имя, что и известное расширение. Также этот метод не работает со скрытыми папками.

Внимание! Это решение является (не очень тщательно протестированным) взломом. Используйте его на свой страх и риск.

для h в $ (ls -A | grep «^\».); делать LS_COLORS="$LS_COLORS*$h=04;05:"; готово; ls -la; eval $ (цирколоры)

-121--42302-

$ echo "duck's" | sed s/\'//
ducks

Но для этого не нужен sed , чистый раствор bash:

$ abc="duck's"; echo ${abc/\'/}
ducks

1
26.02.2015, 00:48
1 ответ

Как вы реализовали свой для . Если у вас есть файлы с пробелами в них. Он будет работать совсем хорошо без переменной, для f in / path / to / files / * , поскольку расширение происходит таким образом, что для петли может понять.

Вообще, поскольку это стоило вам ресурсы для раскрутки новых процессов, лучше всего иметь только один экземпляр awk и, как отметил, как @ JW013, вы должны выполнить разделение снаружи оболочки, поскольку SH и Bash неспособны к математике с плавающей точкой.

Поскольку вам нужно знать конец файла для манипулирования каждой строкой, у вас есть два варианта: прочитайте каждый файл, сохраняя каждую строку для второго читала, или дважды прочитайте каждый файл. Поскольку сохранение больших файлов в памяти может быть проблематичным, я выбрал второй вариант:

for f in /path/to/files/*; do
  echo "$f"
  awk '
    NR == FNR {
      sum += $4;
      next;
    }
    FNR == 1 {
      print "total: " sum;
      SCALEFACTOR = 10000 / sum;
      print SCALEFACTOR;
    }
    {
      printf("%s\t%s\t%s\t%f\n", $1, $2, $3, $4 * SCALEFACTOR);
    }' "$f" "$f"

NR == FNR говорит, что общая запись (строка) номер такой же, как номер записи текущего файла, который означает, что вы находитесь в первом файле, и задача под рукой определяет сумму. Далее предотвращает стрельбу других пунктов. В противном случае, если на первой строке второго чтения файла мы делаем вещи, которые вы имели между вашим awk . Для каждой строки в этом втором чтении мы распечатаем четыре элемента с четвертым элементом, масштабированным, как вы указали.

Вы можете использовать стандартное форматирование строки на этом четвертом пункте, например, Ваши прокомментированные BC Шкала из пяти изменит мой % f на %. 5F

0
28.01.2020, 01:45

Теги

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