В bash есть три варианта: echo -e
, printf
и $ '. .. '
.
Последний из них самый простой:
$ name="Hello"; name=$name$'\033[34m(Test)\e[0m' ; echo "$name"
Hello(Test)
В этом случае цветовой код был сохранен в переменной. Самый простой способ «увидеть» коды (помимо просмотра цвета) - использовать некоторую шестнадцатеричную программу просмотра:
$ echo "$name" | od -vAn -tcx1
H e l l o 033 [ 3 5 m ( T e s t )
48 65 6c 6c 6f 1b 5b 33 35 6d 28 54 65 73 74 29
033 [ 0 m \n
1b 5b 30 6d 0a
Используйте ее, когда вам нужно «увидеть» коды (и почему они работают или не работают).
Цветовые коды уже интерпретированы внутри переменной. Таким образом вы можете создать переменную для некоторого цвета и использовать ее:
$ blue=$'\033[34m'; reset=$'\033[0m'
$ echo "Hello $blue Test $reset Colors"
Другой способ - хранить коды внутри переменной и интерпретировать их каждый раз, когда потребуется их «эффект».
$ blue='\033[34m'; reset='\033[0m'
$ echo "Hello $blue Test $reset Colors"
Hello \033[34m Test \033[0m Colors
$ echo -e "Hello $blue Test $reset Colors"
Hello Test Colors
«Тест» - синий, а «Цвета» - черный (если экран вашей консоли белый).
Команда echo -e
не такая переносимая (и безопасная), как printf:
$ blue='\033[34m'; reset='\033[0m'
$ printf "%s $blue%s $reset%s" "Hello" "Test" "Colors"
Hello Test Colors
Весь список цветов (фон) будет виден с (печатью пробела):
printf '\e[%sm ' {40..47} 0; echo
Или , с цветами переднего плана:
printf '\e[%smColor=%s ' {30..37}{,} 0 0; echo
Вы можете получить почти , используя утилиту Unpand
, чтобы «табулировать» ввод, а затем установить awk
разделитель полей для табуляции и печати только строк, последнее поле которых состоит из чего-то другого, кроме пробелов:
unexpand -t8 input.txt | awk -F'\t' '$NF ~ /[^ ]/ {print $1, $NF}'
usr1 B
usr2 C
usr4 A
usr6 A
Это не работает для строки заголовка, потому что между позициями меньше пробелов
и ref
поля. Если заголовок необходим, вы можете обработать его отдельно:
unexpand -t8 input.txt | awk -F'\t' 'NR == 1 {print $1,$3} $NF ~ /[^ ]/ {print $1, $NF}'
Команда awk - не самый подходящий инструмент для этой работы. Используйте команду cut, которая принимает в качестве аргумента символьные позиции полей, которые вы хотите извлечь. Поэтому в вашем примере укажите, что USERS
начинается с позиции 1 и заканчивается позицией 8, а rslt
начинается с позиции 33.
$ cut -c 1-8,33- input.txt USERS rslt usr1 B usr2 C usr3 usr4 A usr5 usr6 A usr7
О том, как считать позиции символов, см. следующее.
1 2 3 123456789012345678901234567890123456789 USERS position ref rslt usr1 X B usr2 2980 C usr3 3323 P usr4 A usr5 5251 U usr6 9990 A usr7 10345 T
В этом случае одним из возможных решений является чтобы указать ширину полей в начальном разделе:
awk 'BEGIN {FIELDWIDTHS = "16 11 6 7"}
$4 ~/[^ ]/ {print $1 $4}'
Ширина поля может быть подсчитана вручную, но для сложных заголовков я предпочитаю начинать с
head -1 f | grep -Po '.*? (?=\S|$)' | awk '{print length}'
ОБНОВЛЕНИЕ: ... или чтобы иметь дело с начальные и конечные пробелы в заголовке:
head -1 f | grep -Po '(^ *|\S).*?( (?=\S)|$)' | awk '{print length}'