строковые манипуляции без awk или sed

любая помощь по этой проблеме приветствуется У меня есть текстовый файл со следующим форматом

Мы можем с уверенностью предположить, что имена всегда состоят из трех символов, профессия – 7 символов и зарплата 5 символов. Вариабельны поступают с пользовательского ввода, а не как параметры.

BobJanitor20000 TedBuilder30000 NedFighter25000 KitTeacher40000 

Я прошу пользователя ввести имя и другой ввод, показывать ли занятие или зарплату

Если пользователь вводит «Тед» и выбирает зарплату, выход должен быть

 Ted 30000 

В программе также должны учитываться частичные совпадения имени, «ed» и зарплата должны выводиться

 Ted 30000 Ned 25000 

Я знаю, что cut и grep могут дать мне relavent lines, но как мне создать вывод, который я хочу?

6 Solutions collect form web for “строковые манипуляции без awk или sed”

Вот сценарий, который работает для поиска имени. Я использую здесь документ (aka heredoc) вместо внешнего файла, чтобы доставить список в цикл while, чтобы все это содержалось в этом файле для удобства чтения. Вы можете расширить его, как хотите.

Прочтите man bash для получения информации о встроенных командах (и найдите руководство для вещей, которые я сделал полужирным шрифтом) Я использую,

  • Расширение подстроки для получения частей линии
  • Регулярное выражение, чтобы найти совпадение = ~
  • [[ …]] вернуть условное значение (0 или 1) в зависимости от внутреннего выражения

Вот сценарий:

 read -p "Input Name: " SearchName while read line do Name=${line:0:3} Job=${line:3:7} Salary=${line:10:5} [[ $Name =~ $SearchName ]] && echo $Name $Salary done << "end--" BobJanitor20000 TedBuilder30000 NedFighter25000 end-- user@machine:~/tmp$ bash manipvar.sh Input Name: ed Ted 30000 Ned 25000 user@machine:~/tmp$ 
 $ grep -F ed file|fold -w 5|fold -w 3|grep -E '^[[:upper:]]..|^[0-9]'|paste -sd ' \0\n' - Ted 30000 Ned 25000 

Или:

 $ cut -c 1-3,11- file | grep -F ed | fold -w 3 | paste -sd ' \0\n' - Ted 30000 Ned 25000 

Или (при условии GNU grep ):

 $ grep -oE '^.{3}|.{5}$' file | paste -sd ' \n' - | grep -F ed Ted 30000 Ned 25000 

Вы также можете сделать (предполагая оболочку с поддержкой подстановки процесса):

 separate() { fold -w 1 -- "$@" | paste -sd '\0\0 \0\0\0\0\0\0 \0\0\0\0\n' - | sort -k 1,1 } join <(separate file | cut -d ' ' -f 1 | grep -F ed ) <(separate file) | cut -d ' ' -f 1,3 

Предполагая, что разделение основано на заглавной букве.

с SED

имя + зарплата

 sed -e "/${NamePart}.*[AZ].*/ !d" -e 's/\([AZ][az]*\)[AZ][az]*\([0-9]*\)/\1 \2/' YourData.file 

имя + профессия

 sed -e "/${NamePart}.*[AZ].*/ !d" -e 's/\([AZ][az]*\)\([AZ][az]*\)[0-9]*/\1 \2/' YourData.file 

Используйте этот сценарий (чистый баш):

 #!/bin/bash # make the search case insensitive shopt -s nocasematch unset a; declare -A a # read the name and save it in $name read -p "Enter the Name: " name # read the salary or profession and save it in $type select type in salary profession; do # loop trough the file while read l; do # characters 0 to 3 are the name n=${l:0:3} # the profession and the salary a["profession"]="${l:3:7}" a["salary"]="${l:10:5}" # if the name matches print the selected type [[ $n =~ $name ]] && echo "$n ${a[$type]}" done <file # the input file exit done 

Выход:

 $ ./script Enter the Name: ed 1) salary 2) profession #? 1 Ted 30000 Ned 25000 $ ./script Enter the Name: ted 1) salary 2) profession #? 2 Ted Builder $ ./script Enter the Name: 1) salary 2) profession #? 2 Bob Janitor Ted Builder Ned Fighter Kit Teacher 

Это работало для меня

 $ echo `grep -oe '^...\|[0-9]\{5\}' filename` | grep -oe '.\{9,10\}$\?' | grep ed Ted 30000 Ned 25000 

Вот то, что работает в обратном направлении:

 xargs -I{} -n1 \ expr {}\ {} : '[^0-9]*\(.* .ed\).*' 

expr передает две копии каждой строки назад и разделяется пробелом в качестве первого аргумента. Подобно:

 expr 'TedBuilder20000 TedBuilder20000' : '[^0-9]*\(.* .ed\).*' 

И поэтому его соответствие возвращается – если есть – Salary то Name :

 printf %s\\n BobJanitor20000 TedBuilder30000 \ NedFighter25000 KitTeacher40000 | xargs -I{} -n1 \ expr {}\ {} : '[^0-9]*\(.* .ed\).*' 

 30000 Ted 25000 Ned 

Это работает, хотя:

 xargs sh -c <input ' for a do case $a in (?ed*) ! :; esac || printf %-4.3s${a##*[!0-9]}\\n "$a" done' '' 

 Ted 30000 Ned 25000 
  • Как сделать просмотрщик PDF восприимчивым к изменениям в Debian
  • Bash - Разбить предыдущие параметры команд
  • sed: захват и замена всех данных между последней обратной косой чертой и запятой
  • соответствие строки awk из 2 столбцов
  • Есть ли надежный инструмент командной строки для обработки CSV-файлов?
  • Как прочитать файл свойств через мой скрипт?
  • Найти отличия в файле и сортировке файла по ключу
  • Возможно ли напечатать повторяющийся диапазон аргументов через cli из csv? (см. пример)
  • Как сопоставить 2 больших файла и распечатать разницу в сценарии оболочки
  • bash расширяется до того же значения вместо значения строки за строкой в ​​команде sed
  • Удалить до первого вхождения, отредактировать эту строку и распечатать оставшиеся строки без изменений
  • Linux и Unix - лучшая ОС в мире.