Mam długą linię, w której chcę wstawiać spację co 4 znaki na pojedynczej linii pełnego tekstu, aby ułatwić czytanie, jaki jest najprostszy sposób? także powinienem być w stanie wprowadzić linię z potoku. na przykład
echo "foobarbazblargblurg" | <some command here>
daje
foob arba zbla rgbl urg
command-line
shell
text-processing
ksenoterracid
źródło
źródło
sed
że spróbowałem najpierw, że mogłem się kopnąć.'s/.\{4\}/& /g;s/ $//'
Możesz użyć następującego prostego przykładu:
źródło
sed
odpowiedź. Nie wiedziałem o tymfold
wcześniej.fold
nie działa ze znakami wielobajtowymi (jakecho €€€€€€€€ | fold -w4 | paste -sd' ' -
w UTF-8).Oto przykład użycia
grep
ixargs
:źródło
xargs
działaecho
domyślnie, więc nie będzie działać ze słowami typu-nen
lub zawierającymi ukośniki odwrotne w zależności odecho
implementacji. Od czasu do czasu zobaczysz także dziwny znak nowej linii, jeśli xargs działa na więcej niż jednymecho
.paste -sd ' ' -
Zamiast tego lepiej jest potokować . Pamiętaj, że-o
nie jest to standardowa opcja.Tylko w bash, brak zewnętrznych poleceń:
lub jako wersja jednorurowa:
Działa to w ten sposób, że konwertuje każdy znak ciągu na „(.)” W celu dopasowania wyrażenia regularnego i przechwytywania za pomocą
=~
, a następnie po prostu wyprowadza przechwycone wyrażenia zBASH_REMATCH[]
tablicy, pogrupowane według potrzeb. Wiodące / końcowe / pośrednie spacje są zachowane, usuń cudzysłowy,"${BASH_REMATCH[@]:1}"
aby je pominąć.Tutaj jest zawinięty w funkcję, ta przetworzy swoje argumenty lub odczyta stdin, jeśli nie ma żadnych argumentów:
Możesz łatwo sparametryzować liczbę, aby odpowiednio dostosować ciąg formatu.
Dodaje się końcowe miejsce, użyj dwóch
printf
s zamiast jednego, jeśli jest to problem:Pierwszy
printf
drukuje (maksymalnie) pierwsze 4 znaki, drugi warunkowo drukuje wszystkie pozostałe (jeśli występują) z wiodącym odstępem, aby oddzielić grupy. Test obejmuje 5 elementów, a nie 4, które uwzględniają element zerowy.Uwagi:
printf
S”%c
może być stosowany zamiast%s
,%c
(być może) sprawia, że intencją jaśniejsze, ale to nie jest multi-byte bezpieczny charakter. Jeśli twoja wersja bash jest w stanie, powyższe jest bezpieczne dla znaków wielobajtowych.printf
ponownie używa łańcucha formatu, dopóki nie zabraknie argumentów, więc po prostu pochłania 4 argumenty na raz i obsługuje końcowe argumenty (więc nie są potrzebne przypadki krawędziowe, w przeciwieństwie do niektórych innych odpowiedzi, które są prawdopodobnie błędne)BASH_REMATCH[0]
to cały dopasowany ciąg, więc dane wyjściowe zaczynają się od indeksu 1printf -v myvar ...
zamiast tego użyj do zapisania do zmiennejmyvar
(z zastrzeżeniem zwykłego zachowania w pętli odczytu / podpowłoce)printf "\n"
razie potrzebyMożesz włączyć powyższe,
zsh
jeślimatch[]
zamiast tego użyjesz tablicyBASH_REMATCH[]
i odejmiesz 1 od wszystkich indeksów, ponieważzsh
nie zachowuje elementu 0 z całym dopasowaniem.źródło
Z
zsh
tylko:Lub
ksh93
tylko z :Tylko z dowolną powłoką POSIX (unikając również spacji końcowej, jeśli długość wejściowa jest wielokrotnością 4):
To dotyczy postaci . Jeśli chcesz to zrobić w klastrach grafemów (na przykład, aby łamać
Stéphane
, napisane jako$'Ste\u0301phane'
,Stép hane
i nieSte phan e
), zzsh
:Z ksh93 możesz również podzielić według szerokości wyświetlania, co by działało w przypadku
Stéphane
powyższego, ale może również pomóc, gdy w grę wchodzą inne rodzaje znaków o zerowej lub podwójnej szerokości:źródło
Odpowiem tylko wstawiając spacje zgodnie z wymaganiami, aby spacja pojawiała się co najmniej po każdych 4 znakach w linii; nie jestem pewien, w jaki sposób chcesz obsłużyć tę skrzynkę. Na przykład, biorąc pod uwagę wejście „aa bbccdd”, otrzymasz wynik „aa bbcc dd” zamiast „aa b bccd d”.
Używam Perla do wyszukiwania z wyprzedzeniem, ale ogólnie nie znam się zbyt dobrze na Perlu, więc mogą być potrzebne poprawki:
źródło
Zrobiłem to za pomocą Pythona
Najpierw czytam plik, potem dzielę przez 4 znaki i dodam spację
/root/l.txt ==> Składa się z treści podanej w przykładzie
wydajność
źródło