Например, учитывая:
USCAGoleta9311734.5021-120.1287855805
Я хочу извлечь только:
US
Например, учитывая:
USCAGoleta9311734.5021-120.1287855805
Я хочу извлечь только:
US
Ответы:
Вероятно, наиболее эффективный метод, если вы используете 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
- они доставляют первые два символа каждой строки ввода.
Все это не имеет значения, если вы уверены, что вводите одну строку, все они имеют одинаковый эффект.
printf '%s'
вместо echo
в случае , если есть странные символы в строке: stackoverflow.com/a/40423558/895245 Для POSIX одержит: head -c
не POSIX, cut -c
и awk substr
это, sed \1
не уверен.
самый простой способ
${string:position:length}
Где это извлекает $length
подстроку из $string
at $position
.
Это встроенная функция bash, поэтому использование awk или sed не требуется.
Вы получили несколько хороших ответов , и я бы с Bash встроенных себя, но так как вы просили о sed
и awk
и ( почти ) никто другом предложило решение , основанное на них, я предлагаю вам эти:
echo "USCAGoleta9311734.5021-120.1287855805" | awk '{print substr($0,0,2)}'
и
echo "USCAGoleta9311734.5021-120.1287855805" | sed 's/\(^..\).*/\1/'
awk
Один должен быть достаточно очевидно, но вот объяснение sed
одного:
substr($0,1,2)
.
Если вы в игре bash
, вы можете сказать:
bash-3.2$ var=abcd
bash-3.2$ echo ${var:0:2}
ab
Это может быть именно то, что вам нужно ...
Просто grep:
echo 'abcdef' | grep -Po "^.." # ab
-P
опцию, чтобы сделать его короче. Все регулярные выражения поймут этот шаблон.
Вы можете использовать printf
:
$ original='USCAGoleta9311734.5021-120.1287855805'
$ printf '%-.2s' "$original"
US
Действительно, довольно поздно, но вот оно
sed 's/.//3g'
Или
awk NF=1 FPAT=..
Или
perl -pe '$_=unpack a2'
Если вы хотите использовать сценарии оболочки и не полагаться на расширения, отличные от posix (например, так называемые bashisms), вы можете использовать методы, которые не требуют разветвления внешних инструментов, таких как grep, sed, cut, awk и т. Д., Которые затем сделайте ваш сценарий менее эффективным. Возможно, эффективность и переносимость posix не важны для вашего варианта использования. Но в случае, если это так (или просто в качестве хорошей привычки), вы можете использовать следующий метод расширения параметра для извлечения первых двух символов переменной оболочки:
$ sh -c 'var=abcde; echo "${var%${var#??}}"'
ab
При этом используется расширение параметра «наименьший префикс» для удаления первых двух символов (это ${var#??}
часть), затем расширение параметра «наименьший суффикс» ( ${var%
часть) для удаления этой строки, состоящей только из первых двух символов, из оригинала. стоимость.
Этот метод был ранее описан в этом ответе на вопрос «Shell = Проверить, начинается ли переменная с #». В этом ответе также описывается пара похожих методов расширения параметров, которые можно использовать в немного другом контексте, чем тот, который применяется к исходному вопросу здесь.
Если ваша система использует другую оболочку (не 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;"
bash
случае, если вы его еще не использовали.
Ради забавы, я добавлю несколько, которые, хотя и слишком сложны и бесполезны, но не упоминаются:
head -c 2 <( echo 'USCAGoleta9311734.5021-120.1287855805')
echo 'USCAGoleta9311734.5021-120.1287855805' | dd bs=2 count=1 status=none
sed -e 's/^\(.\{2\}\).*/\1/;' <( echo 'USCAGoleta9311734.5021-120.1287855805')
cut -c 1-2 <( echo 'USCAGoleta9311734.5021-120.1287855805')
python -c "print(r'USCAGoleta9311734.5021-120.1287855805'[0:2])"
ruby -e 'puts "USCAGoleta9311734.5021-120.1287855805"[0..1]'
если mystring = USCAGoleta9311734.5021-120.1287855805
print substr(mystring,0,2)
напечатал бы нас
где 0 - начальная позиция, а 2 - как читать разные символы
awk
. Извините, сначала я не мог сказать.
Это то, что тебе нужно?
my $string = 'USCAGoleta9311734.5021-120.1287855805';
my $first_two_chars = substr $string, 0, 2;
ссылка: substr
perl -e 'print substr $ARGV[0], 0, 2' 'USCAGoleta9311734.5021-120.1287855805'