Наприклад, наведено:
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 вбудованих себе, але так як ви просили про 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'