sed :заменить шаблон выводом функции bash

for len in 4 5 8; do
    cut -c "1-$len" file
done

При этом многократно используется cut -cдля вырезания первой части каждой строки файла с именем file. Длина вырезаемого бита зависит от переменной цикла len.

Если вы строго придерживаетесь критерия «одной строки»:

for len in 4 5 8; do cut -c "1-$len" file; done

Или,как простая в использовании функция оболочки:

cut_to_lengths () {
    file=$1; shift
    for len do
        cut -c "1-$len" "$file"
    done
}

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

$ cut_to_lengths file 4 5 8 1
1234
ABCd
12345
ABCde
12345678
ABCdefgi
1
A

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

Для этого мы можем изменить команду cutна команду awk:

awk -v len="$len" 'length >= len { print substr($0, 1, len) }'

Замените cut -c "1-$len"приведенной выше командой awkв приведенном выше коде.

1
28.01.2021, 06:53
2 ответа

Посмотрите внимательно на свой вызов sed, в нем отсутствует закрывающая косая черта команды s///. Затем вы используете двойные кавычки, поэтому даже до запуска sed правая часть команды s/// была заполнена из-за интерполяции двойными кавычками. Это не то, что вы хотите. Тем не менее, это все равно не поможет вам пройти мимо стойки ворот.

В команде GNU sed's s///есть небольшой -известный флаг /e. Это именно то, что доктор прописал в данном случае. Что он делает, так это динамически создает rhs команды s/// на основе запуска кода оболочки, указанного в rhs, и заменяет его своим выводом. Примечание. :Требуется соответствие всему пространству шаблонов.

Это также требует, чтобы ваша пользовательская функция была экспортирована, чтобы быть доступной для дочерних элементов.

#this does not work
##this is what YOU wrote 
y=$(echo "\"bla_x\"" |
sed -e "s/bla/$(xx &)p")

##this now WORKS
export -f xx
y=$(
echo '"bla_x"' |
sed -Ee '
  s/^.(.*)(_x).$/echo "$(xx '"\1"')\2"/e
'
)
echo "$y"
(98,108,97)_x

Обратите внимание на использование одинарных кавычек в команде sed.

2
18.03.2021, 22:34

Если я вас правильно понял, вы можете упростить свою функцию, используяprintf:

xx() {
  # create an array to store every character of the word
  declare -a arr

  # loop the word to every char, removing quotes
  for i in $(echo "${1//\"}" | grep -o.); do 
    # store the ascii value
    arr+=($(printf "%d" "'$i"))
  done 

  # create a variable with the values, comma separated
  printf -v ascii "%s," "${arr[@]}" 

  # print the result adding the parenthesis and removing the last comma
  echo "(${ascii%,})"
}

$ xx "\"bla\""
(98,108,97)

Теперь xxудаляет двойные кавычки, но в вашей команде sedвы пытаетесь отправить шаблон без кавычек (bla, а не «bla» ), поэтому, если вы не хотите, чтобы они вывод следующего кода, вы должны удалить их другим способом:

p=bla
s="\"bla_x\""
c=$(xx "$p")

$ echo "$s" | sed "s/$p/$c/"
"(98,108,97)_x"
1
18.03.2021, 22:34

Теги

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