вырезать с разделителем из 2 символов

Если вы используете X, а не Wayland, использование xmodmapвместо xkbdбудет намного проще (хотя люди скажут вам что xmodmapустарел, но люди говорят об этом уже десять лет, и это все еще существует).

Очень кратко: запустите xmodmap -pke, найдите код для капслока и клавиши больше/меньше, запустите xmodmap -e 'keycode 123 = ... , где 123 — это код клавиши для CapsLock, а ... — это определение клавиши «больше/меньше».

Если это работает, поместите строку в ~/.Xmodmap, ~/.Xkeyboardили что-то еще, что ваш менеджер дисплея читает при входе в систему.

1
22.08.2017, 04:18
4 ответа

Вы можете использовать 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
2
27.01.2020, 23:11

Пример тестового сценария, который мне подходит:

#!/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]
3
27.01.2020, 23:11

awk Разделитель полей обрабатывается как регулярное выражение, если его длина превышает два символа. ..в качестве регулярного выражения означает любые 2 символа. Вам нужно будет избежать этого .либо с помощью [.], либо с помощью \..

awk -F'[.][.]'...
awk -F'\\.\\.'...

(Сама обратная косая черта также должна быть экранирована (с некоторыми awks, такими как gawk по крайней мере )для расширения \n/ \b, которому подвергается аргумент -F).

В вашем случае:

awk -F' +|[.][.]' '/^[^#]/{print $1}' < output.txt

В любом случае, избегайте циклов оболочки для обработки текста , обратите внимание, чтоreadне предназначен для использования таким образом , чтоechoне следует использовать для произвольных данных и не забудьте заключить свои переменные в кавычки .

10
27.01.2020, 23:11

Вы также можете использовать 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

К сожалению, этот метод будет работать только в вашем случае и неприемлем для более широкого спектра входных данных.

0
13.11.2020, 16:48

Теги

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