Использование awk для печати второго столбца и остального текста из #

Похоже, что pdfencryptтребует 8-битный (пароль в кодировке ISO -8859 )и не знает, как обращаться с (, т.е. преобразовывать )UTF -8 паролей.

Вы должны использовать совместимую кодировку символов при выполнении pdfencrypt, для шифрования и дешифрования. Обычный ASCII ("C" )или ISO -8859 -n (, например "de _DE.latin1", как предложил Хауке Лагинг ), должен работать. На мой взгляд, это просто указывает pdfencryptпринимать символы вашего пароля как есть (, т.е. не требуется преобразования ), вот и все.

Просто добавьте эту строку вверху скрипта:

export LC_ALL=de_DE.latin1        # Or fr_FR, or latin15, or... Any valid locale for your system

Или может быть достаточно изменить эту единственную строку:

LC_ALL=de_DE.latin1 pdfencrypt "$1" -p "$password" -o "$2"

Сделайте то же самое для декодирования.

Если вы преобразуете свой пароль с помощью iconvвместо установки LC _ALL, я думаю, у вас будет та же проблема, поскольку pdfencryptвсе еще будет полагать, что вы даете ему UTF -8 символов, когда он встречает 8 бит те.

В любом случае, чтобы упростить задачу, вам, вероятно, следует придерживаться 7-битного набора символов ASCII :, пробела, букв без -акцента, цифр, основных знаков препинания и т. д.(man 7 ascii)

Что касается пробела, вы должны знать, что чтение в определенную переменную с помощью(read -r var)удаляет начальные и конечные пробелы (фактически символы в переменной оболочкиIFS). Это может раздражать для пароля. Вы должны использовать read -r, чтобы поместить всю прочитанную строку в переменную REPLY.

Это дало бы этот код:

export LC_ALL=de_DE.latin1
read -r -s -p "Password: "
echo
pdfencrypt "$1" -p "$REPLY" -o "$2"
0
02.05.2019, 18:34
4 ответа
$ awk -v OFS='\t' '/^bindsym/ { key = $2; sub(".*#", ""); print key, $0 }' file
$mod+F2 Open terminal
$mod+p  Popup Dictionary
$mod+Mod1+l     Dmenu for my books collection
Mod1+Control+b  nnn file browser

Здесь используется awkдля извлечения второго поля в каждой строке, начинающейся с bindsym, в переменную key. Затем он удаляет все до #включительно в строке и печатает keyи оставшуюся часть строки с табуляцией в качестве разделителя.

Альтернативное форматирование вывода:

$ awk '/^bindsym/ { key = $2; sub(".*#", ""); printf("%-20s\t%-20s\n", key, $0) }' file
$mod+F2                 Open terminal
$mod+p                  Popup Dictionary
$mod+Mod1+l             Dmenu for my books collection
Mod1+Control+b          nnn file browser

Логика такая же, но вывод выделяет 20 символов для каждого из двух (левых -выравниваемых )полей и помещает табуляцию в -между ними (для надежности ).

2
28.01.2020, 02:22

Использование функции match()GNU awkдля сопоставления части от #до конца строки

awk '/bindsym/ && match($0,/#(.+)$/,arr){print $2, arr[1]}' filep

Функция match()заполняет массив, указанный в третьем аргументе, совпавшим шаблоном из регулярного выражения во втором аргументе.

в любом POSIX awk, третий аргумент match()не поддерживается , а пара специальных переменных RSTARTи RLENGTH, которые отмечают начало и длина согласованной группы. Мы используем функцию substr()в текущей строке, чтобы получить совпадающую строку

awk '/bindsym/ && match($0,/#(.+)$/){print $2, substr($0,RSTART+1,RLENGTH)}' file

Чтобы красиво -распечатать вывод, вы можете использовать функцию printf(), как в другом ответе.

2
28.01.2020, 02:22
Step1: count=`awk '{print NR}'|sed -n '$p' filename`

Step2:for ((i=1;i<=$count;i++)); do awk -v i="$i" 'NR==i && $0 ~ /^bindsym/{print $2}' filename; sed -n ""$i"s/.*#//p" filename; done| sed "N;s/\n/ /g"


output
for ((i=1;i<=$count;i++)); do awk -v i="$i" 'NR==i && $0 ~ /^bindsym/{print $2}' filename; sed -n ""$i"s/.*#//p" filename; done| sed "N;s/\n/ /g"

$mod+F2 Open terminal 
$mod+p Popup Dictionary  
$mod+Mod1+l Dmenu for my books collection
Mod1+Control+b nnn file browser
-1
28.01.2020, 02:22

Это очень просто сделать в sed; поскольку ваши данные на самом деле не ориентированы на поля, Awk не дает здесь огромных преимуществ:

sed 's/^[^ ]* //;s/.*#//' inputfile

Перевод:

s/^[^ ]* //

Удалить все до первого пробела включительно.

s/.*#//

Удалить все от первого (оставшегося )символа пробела до последнего #символа в строке.

0
28.01.2020, 02:22

Теги

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