Захоплення перших [x] символів для струни з труби


58

Якщо у мене дійсно довгий вихід з команди (один рядок), але я знаю, що хочу лише перші [x] (скажімо, 8) символів виводу, який найпростіший спосіб отримати це? Розмежувачів немає.


Відповіді:


82

Одним із способів є використання cut:

 command | cut -c1-8

Це дасть вам перші 8 символів кожного рядка виводу. Оскільки він cutє частиною POSIX, він, ймовірно, є на більшості Unices.


3
Зверніть увагу, що cut -cвибирає символи; cut -bабо head -cвибирає байти. Це робить різницю в деяких місцевостях (на практиці при використанні UTF-8).
Жил 'ТАК - перестань бути злим'

У цьому випадку також не потрібно вказувати стартовий індекс. Висловлювання cut -c-8буде обрано від 1 до 8
символу

@Steven, cutеквівалент у Windows є?
Pacerier

Також command | dd bs=8 count=1 2>/dev/null. Не кажучи, що це коротше чи вище. Просто ще одна альтернатива.
сумнівним

@Gilles, але зверніть увагу , що з поточною версією GNU cut, cut -cпрацює як cut -b(тобто, він не працює належним чином для багатобайтові символів).
Стефан Шазелас

24

Це деякі інші способи отримати лише перші 8 символів.

command | head -c8

command | awk '{print substr($0,1,8);exit}' 

command | sed 's/^\(........\).*/\1/;q'

І якщо у вас баш

var=$(command)
echo ${var:0:8}

2
Я думаю , що наступна СЄПН формулювання трохи легше читати: command | sed 's/\(.\{8\}\).*/\1/'або якщо ваш СЕД підтримує його: command | sed -r 's/(.{8}).*/\1/'; В іншому випадку +1
Стівен D

Хороший матеріал, але зауважте, що head -cрахує байти , а не символи. Так само серед основних реалізацій Awk тільки GNU awk правильно обробляє багатобайтові символи - FreeBSD Awk та Mawk не роблять.
mklement0

2

Якщо у вас є достатньо вдосконалена оболонка (наприклад, в Bash буде працювати наступне, не впевнений у тирі), ви можете:

read -n8 -d$'\0' -r <(command)

Після виконання read ... <(command)ваші персонажі будуть у змінній оболонки REPLY. Введіть, help readщоб дізнатися про інші параметри.

Пояснення: -n8аргумент readговорить, що нам потрібно до 8 символів. -d$'\0'Каже читання до нуля, а не новий рядок. Таким чином, читання продовжуватиметься для 8 символів, навіть якщо один з попередніх символів є новим рядком (але не, якщо він є нульовим). Альтернативою -n8 -d$'\0'є використання -N8, яке читає рівно 8 символів або поки stdin не досягне EOF. Жоден роздільник не шанується. Це, мабуть, краще відповідає вашим потребам, але я не знаю напевно, скільки снарядів має прочитане, яке вшановує, -Nа не честь -nі -d. Продовжуючи пояснення: -rговорить ignore \-escapes, так що, наприклад, ми трактуємось \\як два символи, а не як одиничні \.

Нарешті, ми робимо це, read ... <(command)а не command | read ...тому, що у другій формі зчитування виконується в підшарці, яка потім негайно виходить, втрачаючи інформацію, яку ви тільки що прочитали.

Інший варіант - зробити всю вашу обробку всередині передплати. Наприклад:

$ echo abcdefghijklm | { read -n8 -d$'\0' -r; printf "REPLY=<%s>\n" "$REPLY"; }
REPLY=<abcdefgh>

1
Якщо ви просто хочете вивести 8 символів, і вам не потрібно обробляти їх у оболонці, просто використовуйте cut.
сумнівним

Приємно знати про це read -n <num>; невеликий застереження: Bash 3.x (досі актуальний в ОС) помилково інтерпретується <num>як кількість байтів і, таким чином, не працює з багатобайтовими символами; це було зафіксовано в Bash 4.x.
mklement0

Це чудова і корисна відповідь. Набагато загальніші за інші.
not2qubit

2

Ще одне рішення вкладиша за допомогою розширення параметрів

echo ${word:0:x}

EG: word="Hello world"
echo ${word:0:3} or echo ${word::3} 
o/p: Hel


EG.2: word="Hello world"
echo ${word:1:3}
o/p: ell

Ви також можете використовувати змінну, що тримає довжину, наприклад: x=8; echo ${word:0:$x}замість жорсткого кодування цілого числа.
Cometsong

1

Це портативний:

a="$(command)"             # Get the output of the command.
b="????"                   # as many ? as characters are needed.
echo ${a%"${a#${b}}"}      # select that many chars from $a

Для побудови рядка змінної довжини символів тут є власне питання .


0

У мене була ця проблема під час генерації файлів контрольної суми вручну в сховищі Maven. На жаль, cut -cзавжди виводиться новий рядок в кінці виходу. Щоб придушити, що я використовую xxd:

command | xxd -l$BYTES | xxd -r

Він виводить рівно $BYTESбайти, якщо тільки commandвихідний коротший, то саме такий вихід.


Ще один спосіб зняти з cutнового | tr -d '\n'
каналу
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.