Добавление недостающих нулей в начале каждой строки, где меньше 4 знаков

В качестве альтернативы вы можете просто запустить новую оболочку bash и загрузить ее оттуда:

ksh$ bash
bash$ source myVenv/bin/activate
(myVenv) bash$ python...

В качестве бонуса это дает вам простой способ деактивировать venv и вернуться в исходную среду :просто exitиз оболочки bash, и вы вернетесь в ksh!

1
05.08.2019, 17:49
11 ответов

Вы можете добавить 4 лидирующих нуля ко всем строкам,а затем получить 4 последних символа каждого:

sed 's/^/0000/; s/^.*\(.\{4\}\)/\1/' < file

Или чтобы избежать усечения чисел, длина которых превышает 4 цифры:

sed 's/^/0000/; s/^.\{1,4\}\(.\{4\}\)/\1/' < file
5
27.01.2020, 23:12

Если значения уже находятся внутри оболочки и являются шестнадцатеричными числами:

$ set -- 30 1 508 A0EA A0EB A0EC A0ED
$ for var; do printf '%04X\n' "0x$var"; done
0030
0001
0508
A0EA
A0EB
A0EC
A0ED

Если значения строки могут быть любой строкой (, даже длиннее 4 символов ), а lineсодержит значение (s )строки, решение усложняется:

[ "${#line}" -lt 4 ] && 
    printf '%0*d%s\n' "$((4-${#line}))" 0 "$line" || 
        printf '%s\n' "${line}"

напечатает значение с таким количеством нулей, которое необходимо для длины строки в 4 символа.

Затем для внешнего файла (решения sed и awk работают быстрее для внешних файлов ), создайте цикл и расширьте код, чтобы сделать его более разборчивым, как:

while read -r line; do
    if [ "${#line}" -lt 4 ]; then 
        printf '%0*d%s\n' "$((4-${#line}))" 0 "$line"
    else
        printf '%s\n' "${line}"
    fi
done <file
0
27.01.2020, 23:12

С помощью GNU awk для strtonum (), если вы вводите шестнадцатеричные числа:

$ awk '{printf "%04X\n", strtonum("0x"$0)}' file
0030
0001
0508
A0EA
A0EB
A0EC
A0ED

С GNU awk независимо от того, является ли ваш ввод шестнадцатеричным или нет:

$ awk '{print gensub(/ /,0,"g",sprintf("%4s",$0))}' file
0030
0001
0508
A0EA
A0EB
A0EC
A0ED

С любым awk независимо от того, является ли ваш ввод шестнадцатеричным или нет:

$ awk '{v=sprintf("%4s",$0); gsub(/ /,0,v); print v}' file
0030
0001
0508
A0EA
A0EB
A0EC

или даже:

$ awk '{$0=sprintf("%4s",$0); gsub(/ /,0)} 1' file
0030
0001
0508
A0EA
A0EB
A0EC
A0ED
1
27.01.2020, 23:12

В оболочке zshвы можете использовать l:length::string:левый -флаг расширения параметра заполнения.

$ var=FF
$ echo ${(l:4::0:)var}
00FF

Чтобы применить его к каждому слову в файле:

printf '%s\n' ${(l:4::0:)$(<file)}

Обратите внимание, что этот оператор также обрезает слова, длина которых превышает 4 символа.

0
27.01.2020, 23:12

Менее элегантный способ:

cat file | sed 's/^\(...\)$/0\1/' | sed 's/^\(..\)$/00\1/' | sed 's/^\(.\)$/000\1/'
1
27.01.2020, 23:12
$ perl -ne 'printf "%05s", $_' ip.txt
0030
0001
0508
A0EA
A0EB
A0EC
A0ED

Здесь используется 5вместо 4, так как в каждой строке есть символ новой строки. Строки, содержащие более 5 символов, будут напечатаны как есть.

0
27.01.2020, 23:12

Еще один для микса:

$ numfmt --format='%04.0f' --invalid=ignore < file
0030
0001
0508
A0EA
A0EB
A0EC
A0ED

numfmtпредоставляется пакетом GNU Coreutils.

3
27.01.2020, 23:12

Использование Posix sed:

  sed -e ':a;s/^.\{0,3\}$/0&/;ta'
0
27.01.2020, 23:12
cat file.txt | awk -vlen=4 '{
  add=""          #empty prefix to be added

  if(length($1)!=len){
       for(i=(len-length($1));i<=length($1);i++)
           add=add"0"          #add prefix as necessary
  }

  print $1""add

 }'

Не стесняйтесь изменять переменную lenпо своему вкусу.

0
27.01.2020, 23:12

Я сделал это, используя условие if и awk

count_line=`awk '{print NR}' p.txt| sed -n '$p'`

for ((i=1;i<=$count_line;i++)); do j=`awk -v i="$i" -F "" 'NR==i{print NF}' p.txt`; if [[ $j == "1" ]]; then awk -v i="$i" -F "" 'NR==i{print "000"$0}' p.txt; elif [[ $j == "2" ]]; then awk -v i="$i" -F "" 'NR==i{print "00"$0}' p.txt ; elif [[ $j == "3" ]]; then awk -v i="$i" -F "" 'NR==i{print "0"$0}' p.txt; else awk -v i="$i" 'NR==i{print $0}' p.txt; fi; done

выход

0030
0001
0508
A0EA
A0EB
A0EC
A0ED
-1
27.01.2020, 23:12

Это немного хромает, (файлы должны быть короче getconf ARG_MAXбайт ), но это работает:

printf '%4s\n' $(<file) | tr ' ' 0
0
27.01.2020, 23:12

Теги

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