Если вы используете X, а не Wayland, использование xmodmap
вместо xkbd
будет намного проще (хотя люди скажут вам что xmodmap
устарел, но люди говорят об этом уже десять лет, и это все еще существует).
Очень кратко: запустите xmodmap -pke
, найдите код для капслока и клавиши больше/меньше, запустите xmodmap -e 'keycode 123 = ...
, где 123
— это код клавиши для CapsLock, а ...
— это определение клавиши «больше/меньше».
Если это работает, поместите строку в ~/.Xmodmap
, ~/.Xkeyboard
или что-то еще, что ваш менеджер дисплея читает при входе в систему.
Вы можете использовать IFS для разделения каждой строки, отбрасывая поле между двумя точками:
#/bin/sh
while IFS=\. read a _ b
do
echo "field one=[$a] field two=[$b]"
done < "file"
Выполнить:
$ ./script
field one=1F3C6 field two=1F3CA
field one=1F3CF field two=1F3D3
field one=1F3E0 field two=1F3F0
Предположим, что файл:
$ cat file
1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0
Пример тестового сценария, который мне подходит:
#!/bin/sh
raw="1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0"
for r in $raw
do
f1=`echo "${r}" | cut -d'.' -f1`
f2=`echo "${r}" | cut -d'.' -f2`
f3=`echo "${r}" | cut -d'.' -f3`
echo "field 1:[${f1}] field 2:[${f2}] field 3:[${f3}]"
done
exit
И вывод:
field 1:[1F3C6] field 2:[] field 3:[1F3CA]
field 1:[1F3CF] field 2:[] field 3:[1F3D3]
field 1:[1F3E0] field 2:[] field 3:[1F3F0]
Редактировать
После прочтения комментария Stéphane Chazelas и ссылки на вопросы и ответы я повторно -написал выше, чтобы удалить loop
.
Я не мог придумать, как убратьloop
и части, например, как переменные (; $f1
, $f2
и $f3
в моем первоначальном ответе ), которые можно было передать. Тем не менее я не знаю, что требовалось на выходе в исходном вопросе.
Во-первых, по-прежнему используетсяcut
:
#!/bin/sh
raw="1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0"
printf '%s\n' "${raw}" | cut -d'.' -f1,3
Что будет выведено:
1F3C6.1F3CA
1F3CF.1F3D3
1F3E0.1F3F0
Можно заменить отображаемый .
любой строкой, используя --output-delimiter=STRING
.
Далее, с sed
вместо cut
, чтобы обеспечить больший контроль над выходом:
#!/bin/sh
raw="1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0"
printf '%s\n' "${raw}" | sed 's/^\(.*\)\.\.\(.*\)$/field 1 [\1] field 2 [\2]/'
И это сделает:
field 1 [1F3C6] field 2 [1F3CA]
field 1 [1F3CF] field 2 [1F3D3]
field 1 [1F3E0] field 2 [1F3F0]
awk
Разделитель полей обрабатывается как регулярное выражение, если его длина превышает два символа. ..
в качестве регулярного выражения означает любые 2 символа. Вам нужно будет избежать этого .
либо с помощью [.]
, либо с помощью \.
.
awk -F'[.][.]'...
awk -F'\\.\\.'...
(Сама обратная косая черта также должна быть экранирована (с некоторыми awks, такими как gawk по крайней мере )для расширения \n
/ \b
, которому подвергается аргумент -F
).
В вашем случае:
awk -F' +|[.][.]' '/^[^#]/{print $1}' < output.txt
В любом случае, избегайте циклов оболочки для обработки текста , обратите внимание, чтоread
не предназначен для использования таким образом , чтоecho
не следует использовать для произвольных данных и не забудьте заключить свои переменные в кавычки .
Вы также можете использовать rev
для возврата строки:
cat data.txt
1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0
Первый столбец:
cat data.txt | cut -d. -f1
1F3C6
1F3CF
1F3E0
Последний столбец:
cat data.txt | rev | cut -d. -f1 | rev
1F3CA
1F3D3
1F3F0
К сожалению, этот метод будет работать только в вашем случае и неприемлем для более широкого спектра входных данных.