Pobieranie pierwszych [x] znaków dla ciągu z potoku


Odpowiedzi:


82

Jednym ze sposobów jest użycie cut:

 command | cut -c1-8

To da ci pierwsze 8 znaków każdego wiersza wyniku. Ponieważ cutjest częścią POSIX, prawdopodobnie znajdzie się na większości Unices.


3
Zauważ, że cut -cwybiera znaki; cut -blub head -cwybiera bajty. To robi różnicę w niektórych lokalizacjach (w praktyce, gdy używasz UTF-8).
Gilles „SO- przestań być zły”

W tym przypadku nie musisz również określać indeksu początkowego. Powiedzenie cut -c-8wybierze postać od 1 do 8.
Sparhawk

@Steven, cutodpowiednikiem w systemie Windows jest?
Pacerier,

Również command | dd bs=8 count=1 2>/dev/null. Nie mówiąc, że jest krótszy lub lepszy. Po prostu kolejna alternatywa.
dubiousjim

@Gilles, ale należy pamiętać, że przy obecnych wersji GNU cut, cut -cdziała jak cut -b(to znaczy, że nie działa prawidłowo dla znaków wielo-bajtowych).
Stéphane Chazelas,

24

Są to inne sposoby na uzyskanie tylko pierwszych 8 znaków.

command | head -c8

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

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

A jeśli masz bash

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

2
Myślę, że następujący preparat sed jest nieco łatwiejsze do odczytania: command | sed 's/\(.\{8\}\).*/\1/'czy jeśli sed wspiera go: command | sed -r 's/(.{8}).*/\1/'; W przeciwnym razie +1
Steven D

Dobre rzeczy, ale pamiętaj, że head -cliczy się bajty , a nie znaki. Podobnie, wśród głównych implementacji Awk, tylko awk GNU obsługuje poprawnie znaki wielobajtowe - Awk FreeBSD i Mawk nie.
mklement0

2

Jeśli masz dostatecznie zaawansowaną powłokę (na przykład następujące polecenia będą działać w Bash, nie masz pewności co do myślnika), możesz:

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

Po wykonaniu read ... <(command)twoje postacie będą w zmiennej powłoki REPLY. Wpisz, help readaby dowiedzieć się o innych opcjach.

Objaśnienie: -n8argument readmówi, że chcemy mieć do 8 znaków. -d$'\0'Mówi czytać aż null, zamiast do nowej linii. W ten sposób odczyt będzie kontynuowany przez 8 znaków, nawet jeśli jeden z wcześniejszych znaków jest znakiem nowej linii (ale nie, jeśli jest pusty). Alternatywą -n8 -d$'\0'jest użycie -N8, która odczytuje dokładnie 8 znaków lub dopóki standardowe wejście nie osiągnie EOF. Żaden ogranicznik nie jest honorowany. To prawdopodobnie lepiej pasuje do twoich potrzeb, ale nie wiem od razu, ile skorup ma odczyt, który honoruje, -Na nie honoruje -ni -d. Kontynuując wyjaśnienie: -rmówi ignoruj \-scapes, tak że na przykład traktujemy \\jak dwie postacie, a nie pojedyncze \.

Wreszcie robimy to read ... <(command)raczej niż command | read ...dlatego, że w drugiej formie odczyt jest wykonywany w podpowłoce, która jest następnie natychmiast zamykana, tracąc właśnie przeczytane informacje.

Inną opcją jest wykonanie całego przetwarzania w podpowłoce. Na przykład:

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

1
Jeśli chcesz tylko wypisać 8 znaków i nie musisz przetwarzać ich w powłoce, po prostu użyj cut.
dubiousjim

Dobrze wiedzieć o read -n <num>; małe zastrzeżenie: Bash 3.x (wciąż obecny na OS) błędnie interpretuje <num>jako bajt liczby, a tym samym nie ze znaków wielo-bajtowych; zostało to naprawione w Bash 4.x.
mklement0

To świetna i przydatna odpowiedź. Znacznie bardziej ogólny niż inne.
not2qubit

2

Kolejne rozwiązanie liniowe z wykorzystaniem rozszerzenia parametrów

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

Możesz także użyć zmiennej o długości, np .: x=8; echo ${word:0:$x}zamiast zakodować liczbę całkowitą.
Cometsong

1

To jest przenośne:

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

Zbudować ciąg znaków o zmiennej długości ma tutaj swoje własne pytanie .


0

Miałem ten problem podczas ręcznego generowania plików sum kontrolnych w repozytorium maven. Niestety cut -czawsze drukuje nowy wiersz na końcu wydruku. Aby stłumić to, którego używam xxd:

command | xxd -l$BYTES | xxd -r

Wyprowadza dokładnie $BYTESbajty, chyba że commandwynik jest krótszy, to dokładnie to wyjście.


inną metodą zdejmowania cut| tr -d '\n'
ostatniej
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.