Mam plik f1.txt
:
ID Name
1 a
2 b
3 g
6 f
Liczba spacji nie jest stała. Jaki jest najlepszy sposób, aby zastąpić wszystkie białe spacje tylko jedną spacją tr
?
Oto co mam do tej pory:
cat f1.txt | tr -d " "
Ale wynik jest następujący:
IDName
1a
2b
3g
6f
Ale chcę, aby wyglądało to tak:
ID Name
1 a
2 b
3 g
6 f
Staraj się unikać sed
.
sed
. Chciałem poznać inne sposobyOdpowiedzi:
Za
tr
pomocą opcji powtarzanias
queeze :Lub możesz użyć
awk
rozwiązania:Po zmianie pola w rekordzie
awk
przebuduj$0
, zabiera wszystkie pola i łączy je razem, oddzieloneOFS
znakiem, który jest domyślnie spacją.Spowoduje to wyciśnięcie sekwencji spacji i tabulatorów (i ewentualnie innych pustych znaków w zależności od ustawień regionalnych i implementacji
awk
) w jedną spację, ale również usunie początkowe i końcowe spacje z każdej linii.źródło
awk
, może zrobić wszystko. Możesz także zaakceptować jego rozwiązanie. Tylko jedna rzecz: Gnouc, czy możesz wyjaśnić, co robi format awk w twoim poleceniu? Czy możesz także dodać tabulatory / spacje, aby dane wyjściowe były zgodne z oczekiwanymi danymi wyjściowymi Nieznanego?column -t
robi. Dodaj wyjaśnienie dlaawk
.tr
zastąpi dwie spacje na końcu linii pojedynczą spacją.awk
usunie wszystkie spacje końcowe.Po prostu użyj
column
:Wynik:
źródło
column -t f1.txt | cut -d " " -f2
Ale nie było to rozwiązanie, którego się spodziewałemcolumn -t file | awk '{print $2}'
drukuje tylko drugą kolumnęJeśli chcesz ściśnąć „białą spację”, będziesz chciał użyć predefiniowanych zestawów znaków tr „: blank:” (pozioma biała spacja i spacja) lub „: space:” (verical biała spacja):
Przykłady uruchomiono na Red Hat 5 (GNU tr).
W moim przypadku chciałem znormalizować wszystkie białe spacje do jednej spacji, aby móc polegać na spacji jako delmiterze.
Jak wskazał drugi komentarz dastrobu, brakowało mi sformułowania na stronie podręcznika:
To pozwala nam wyeliminować pierwszy tr. Kudo będzie szukał swoich cierpliwości w obliczu mojej gęstości.
Wcześniej parsowanie portu z konfiguracji Redis. plik:
Po, z ustawieniem SET2 za pomocą ściśnięcia:
Wynik:
Więcej informacji na temat niuansów białych znaków
Zademonstruj, gdzie samo ściśnięcie kończy się niepowodzeniem, gdy w grę wchodzą kolejne mieszane postacie należące do klasy znaków [: blank:]:
Uwaga: Moje dwa pola ciągów w formacie printf są oddzielone 1 spacją, 1 tabulacją, 1 spacją. Po ściśnięciu ta sekwencja wciąż istnieje. Na wyjściu zrzutu ósemkowego jest to reprezentowane przez sekwencję ascii 040 011 040.
źródło
tr "[:blank:]" " " | tr -s "[:blank:]"
? Myślę, że pierwsza część wystarczy, tj.tr "[:blank:]" " "
Ponieważ normalizuje białe spacje i dokonuje już podstawienia. Ze strony podręcznika: „Ściśnij wiele wystąpień znaków [...] Dzieje się tak po zakończeniu usuwania i tłumaczenia.”printf 'ID \t Name\n' | tr -s "[:blank:]" " " | od -cb
(jak sugeruje @dastrobu) i dostałemID Name\n
(z jedną spacją) jako wynik. Czy rzeczywiście próbowałeś, @ user3183018?printf 'ID␣\t␣Name\n' | tr -s "[:blank:]" "␣"
(jak sugeruje @dastrobu), gdzie␣
reprezentuje spację, i dostałemID␣Name\n
(z jedną spacją) jako wynik. Jest to dokładnie to samo, co w przykładzie „Port <SPACE> <TAB> <SPACE> 6379”, z tym wyjątkiem, że użyłem ciągów nagłówka z pytania. Zastanawiam się, czy próbowałeśtr -s "[:blank:]"
(bez ostatniego"␣"
argumentu).printf 'ID \t Name\n' | od -cb
, pokazuje dokładnie, co powinno:I
D
\t
N
a
m
e
\n
(tjI
D
040
011
040
N
a
m
e
\n
.). Tymczasem, na podstawie własnych dowodów, popełniasz dokładnie taki błąd, jak się spodziewałem: działasztr -s "[:blank:]"
(tj.tr
Z jedną opcją i jednym argumentem), zamiast polecenia, które @dastrobu i ja przedstawiliśmy teraz cztery razy:tr -s '[:blank:]' '␣'
(tj.tr
z jedną opcją i dwoma argumentami ).Kto potrzebuje programu (innego niż powłoka)?
Jeśli chcesz, aby wartości w drugiej kolumnie były wyrównane, jak w
column
odpowiedzi polimorficznej , użyjprintf
zamiastecho
:źródło
tr
wywołania - nie wspominając już o tym, ile więcej pracy zajmuje napisanie. Na koniec, czy nie powiedziałbyś, że ten post nie odpowiada na zadane pytanie? Jaki jest najlepszy sposób zastąpienia wszystkich białych spacji jedną spacją za pomocą tylko tr?$IFS
? Może jakIFS=' <tab>' set -f ; echo $(cat <file)
:?To stare pytanie i rozwiązane wiele razy. Tylko dla kompletności: miałem problem z symulacją, ale chciałem przekazać linie rurą do programu antother. Użyłem xargs .
więc
cat f1.txt | xargs -L1
wydaje się, że generuje dokładnie to, czego chcesz.źródło