Подтвердить что ты не робот

Как извлечь первые два символа строки в сценарии оболочки?

Например, учитывая:

USCAGoleta9311734.5021-120.1287855805

Я хочу извлечь только:

US
4b9b3361

Ответ 1

Вероятно, самый эффективный метод, если вы используете оболочку bash (и, по-вашему, на основе ваших комментариев), следует использовать вариант расширения подстроки:

pax> long="USCAGol.blah.blah.blah"
pax> short="${long:0:2}" ; echo "${short}"
US

Это установит short как первые два символа long. Если long короче двух символов, short будет идентичен ему.

Этот метод в оболочке обычно лучше, если вы собираетесь делать это много (например, 50 000 раз на отчет, как вы упоминаете), поскольку нет накладных расходов на процесс. Все решения, которые используют внешние программы, будут страдать от этих накладных расходов.

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

pax> long="A"
pax> tmpstr="${long}.."
pax> short="${tmpstr:0:2}" ; echo "${short}"
A.

Это гарантировало бы, что все, что меньше двух символов в длину, было заполнено справа с помощью периодов (или что-то еще, просто изменив символ, используемый при создании tmpstr). Не ясно, что вам это нужно, но я подумал, что поставлю его для полноты.


Сказав это, существует множество способов сделать это с помощью внешних программ (например, если у вас нет bash, доступных вам), некоторые из которых:

short=$(echo "${long}" | cut -c1-2)
short=$(echo "${long}" | head -c2)
short=$(echo "${long}" | awk '{print substr ($0, 0, 2)}'
short=$(echo "${long}" | sed 's/^\(..\).*/\1/')

Первые два (cut и head) идентичны для однострочной строки - они в основном оба просто вернут вам первые два символа. Они отличаются тем, что cut предоставит вам первые два символа каждой строки, а head предоставит вам первые два символа всего ввода

Третий использует функцию подстроки awk для извлечения первых двух символов, а четвертый использует sed группы захвата (используя () и \1) для захвата первых двух символов и замены всего с ними. Они оба похожи на cut - они доставляют первые два символа каждой строки на входе.

Ничто из этого не имеет значения, если вы уверены, что ваш ввод является одной строкой, все они имеют одинаковый эффект.

Ответ 2

Самый простой способ -

${string:position:length}

Если это извлекает подстроку $length из $string в $position.

Это bash встроенный, поэтому awk или sed не требуется.

Ответ 3

У вас есть несколько хороших ответов, и я бы пошел с встроенным Bash, но, поскольку вы спросили о sed и awk и (почти), никто другой не предлагал решений на их основе, я предлагаю вы:

echo "USCAGoleta9311734.5021-120.1287855805" | awk '{print substr($0,0,2)}'

и

echo "USCAGoleta9311734.5021-120.1287855805" | sed 's/\(^..\).*/\1/'

awk нужно быть достаточно очевидным, но здесь объяснение sed one:

  • заменить "s/"
  • группа "()" двух из любых символов "..", начиная с начала строки "^" и сопровождаемая любым символом ".". повторяющиеся ноль или более раз "*" (обратные косые черты необходимы для выхода из некоторых специальных символов)
  • через "/" содержимое первой (и только в этом случае) группы (здесь обратная косая черта - это специальный выход, относящийся к соответствующему подвыражению)
  • done "/"

Ответ 4

Просто grep:

echo 'abcdef' | grep -Po "^.."        # ab

Ответ 5

Если вы находитесь в bash, вы можете сказать:

bash-3.2$ var=abcd
bash-3.2$ echo ${var:0:2}
ab

Это может быть именно то, что вам нужно...

Ответ 6

colrm - удалить столбцы из файла

Чтобы оставить первые два символа, просто удалите столбцы, начиная с 3

cat file | colrm 3

Ответ 7

Довольно поздно, но здесь

sed 's/.//3g'

или

awk NF=1 FPAT=..

или

perl -pe '$_=unpack a2'

Ответ 8

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

strEcho='echo ${str:0:2}' # '${str:2}' if you want to skip the first two characters and keep the rest
bash -c "str=\"$strFull\";$strEcho;"

Ответ 9

Если вы хотите использовать сценарии оболочки и не полагаться на не-posix-расширения (такие как так называемые bashisms), вы можете использовать методы, которые не требуют разветвления внешних инструментов, таких как grep, sed, cut, awk и т.д., Которые затем сделать ваш сценарий менее эффективным. Возможно, эффективность и переносимость posix не важны в вашем случае использования. Но в случае, если это так (или просто как хорошая привычка), вы можете использовать следующий метод параметра расширения параметра, чтобы извлечь первые два символа переменной оболочки:

$ sh -c 'var=abcde; echo "${var%${var#??}}"'
ab

При этом используется расширение параметра "наименьший префикс" для удаления первых двух символов (это часть ${var#??}), затем расширение параметра "наименьший суффикс" (часть ${var%) для удаления этого все-но- строка первых двух символов из исходного значения.

Этот метод был ранее описан в этом ответе на вопрос "Shell = Проверить, если переменная начинается С#". Этот ответ также описывает пару похожих методов расширения параметров, которые можно использовать в несколько ином контексте, чем тот, который применяется к исходному вопросу здесь.

Ответ 10

Это то, что вы после?

my $string = 'USCAGoleta9311734.5021-120.1287855805';

my $first_two_chars = substr $string, 0, 2;

ref: substr

Ответ 11

if mystring = USCAGoleta9311734.5021-120.1287855805

print substr(mystring,0,2)

будет печатать US

где 0 - начальная позиция, а 2 - то, как читать мёртвые символы

Ответ 12

perl -ple 's/^(..).*/$1/'

Ответ 13

Вы можете использовать printf:

$ original='USCAGoleta9311734.5021-120.1287855805'
$ printf '%-.2s' "$orginal"
US