awk - замените номер более 17 цифр в столбце с -

cat "$file" #(before)
1
2 </head>
3
4 </head>
5
6 </head>

strToInsert="hello world"
lnum=($(sed -n '/<\/head>/=' "$file"))  # make array of line numbers
((lnum>0)) && sed -i "${lnum[$((${#lnum[@]}-1))]}i \
                      $strToInsert" "$file"

cat "$file" #(after)
1
2 </head>
3
4 </head>
5
hello world
6 </head>
3
03.10.2018, 01:56
4 ответа

Я бы пошел с этим вариантом, используя awk (и sed, чтобы заменить конечный ORS на новую строку ), которая проверяет наличие строк длиной 17 символов или более.

awk -vRS='[|\n]' -vORS='|' 'length($0)>=17{$0="-"}1' | sed 's/|$/\n/'

Чтобы отфильтровать только номера с более чем 17 цифрами, выполните:

awk -vRS='[|\n]' -vORS='|' 'log($0)/log(2)>=17{$0="-"}1' | sed 's/|$/\n/'

Существуют также приемы, позволяющие вообще избежать использования sed и использовать один процесс awk, например здесь:https://stackoverflow.com/questions/34684958/make-the-record-seperator-in-awk-not-apply-after-the-last-record

Таким образом, мы используем возможности разделения и фильтрации записей awk, и мы можем иметь более точное управление фильтром, в отличие от регулярного выражения.

Проверочное испытание:

$ awk -vRS='[|\n]' -vORS='|' 'length($0)>=17{$0="-"}1' <<< '+1234|2|12|1|1|1537820114232192380|0  +1234|2|12|1|1|1537820113262689150|0' | sed 's/|$/\n/'
+1234|2|12|1|1|-|0  +1234|2|12|1|1|-|0

$ awk -vRS='[|\n]' -vORS='|' 'log($0)/log(2)>=17{$0="-"}1' <<< '+1234|2|12|1|1|1537820114232192380|0  +1234|2|12|1|1|1537820113262689150|0' | sed 's/|$/\n/'
+1234|2|12|1|1|-|0  +1234|2|12|1|1|-|0
0
27.01.2020, 21:12

Если по какой-либо причине вы хотите избежать использования регулярных выражений или инструментов помимо awk, вы можете использовать условия awk .

echo "+1234|2|12|1|1|1537820114232192380|0  +1234|2|12|1|1|1537820113262689150|0" | awk -F'|' 'OFS="|" { for (i = 1; i <= NF; i++) { if (length($i) > 17) { $i = "-"} } print; }'

+1234|2|12|1|1|-|0  +1234|2|12|1|1|-|0

Пояснение:

-F'|'                            # Set input field-separator to bar
'OFS="|"                         # Set output field-separator to bar
{ for (i = 1; i <= NF; i++) {    # Loop through the fields
if (length($i) > 17) { $i = "-"} # Set a field with length over 17 to "-"
} print; }'                      # Print output of all fields after this process
1
27.01.2020, 21:12

Вы можете использовать awkследующим образом:

echo "+1234|2|12|1|1|1537820114232192380|0  +1234|2|12|1|1|1537820113262689150|0" | awk '{gsub("[0-9]{18,}", "-")}1'
  +1234|2|12|1|1|-|0  +1234|2|12|1|1|-|0

Вы можете использовать sedследующим образом:

  echo "+1234|2|12|1|1|1537820114232192380|0  +1234|2|12|1|1|1537820113262689150|0" | sed -r 's/[0-9]{18,}/-/g'
  +1234|2|12|1|1|-|0  +1234|2|12|1|1|-|0
3
27.01.2020, 21:12

Поскольку это находится внутри file, быстрее использовать sed:

sed -i 's/[0-9]\{18,\}/-/g' file

Имейте в виду, что опция -iизменит ваш файл. Если вы хотите увидеть, что он делает перед фиксацией, удалите -i.

Обратите внимание, что в BSD -iдолжен иметь параметр, поэтому используйте:-i ''.

Awk тоже мог это сделать:

<file awk '{gsub("[0-9]{18,}", "-")}1'  >newfile
3
27.01.2020, 21:12

Теги

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