Наприклад, наведено:
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підрядку з $stringat $position.
Це башти, вбудовані, тому не потрібно пробуджувати або сідати.
Ви отримали кілька хороших відповідей , і я б з 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
Це може бути саме те, що вам потрібно ...
Просто греп:
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'
Якщо ви хочете використовувати сценарій оболонки, а не покладатися на розширення без посівок (наприклад, так звані башизми), ви можете використовувати методи, які не потребують розщеплення зовнішніх інструментів, таких як grep, sed, cut, awk тощо, які потім зробіть ваш сценарій менш ефективним. Можливо, ефективність та переносність пози не важливі у вашому випадку використання. Але у випадку, якщо це (або як корисна звичка), ви можете скористатися наступним методом розширення параметрів, щоб витягти перші два символи змінної оболонки:
$ 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;
посилання: субстр
perl -e 'print substr $ARGV[0], 0, 2' 'USCAGoleta9311734.5021-120.1287855805'