To powinno być naprawdę proste, ale z jakiegoś powodu nie działa:
sed -i.bak -E 's/\t/ /' file.txt
Zamiast zastępować znaki tabulacji, zastępuje t
znaki. Wypróbowałem każdą odmianę, o której mogłem pomyśleć, bawiąc się cytowaniem itp. Poszukałem google i znalazłem, że wszyscy używają podobnych wyrażeń i wydaje się, że działają dla nich.
To -E
jest OS X. Myślałem, że niepowodzenie może być wynikiem dziwnego dziwactwa OS X sed
, więc wypróbowałem to również z Ruby (bez -i
) i uzyskałem ten sam wynik:
ruby -pe '$_.gsub!(/\t/," ")' < file.txt > file.new
Używam Bash 3.2.51 na OS X i iTerm, chociaż nie widzę, jak którekolwiek z nich może być bardzo istotne. Nie ustawiłem żadnych dziwnych zmiennych środowiskowych, choć mogę opublikować dowolne, które Twoim zdaniem mogą być istotne.
Co może być nie tak?
UPDATE : Muszę dokonały jakiś inny błąd lub literówka kiedy próbowałem wersji Ruby, ponieważ Gilles zaznacza, że robi pracę (a ja nigdy nie miałem go skierować mnie źle!). Nie jestem pewien, co się stało, ale jestem prawie pewien, że to był mój błąd.
źródło
\t
w miejscused
, wCTRL-V<TAB>
którym<TAB>
znajduje się klawisz Tab iCTRL-V
klawisz Control iv
naciśnięcie razem.Odpowiedzi:
Składnia
\t
znaku tabulacji w sed nie jest standardowa. Ta ucieczka jest rozszerzeniem GNU sed . W Internecie znajduje się wiele przykładów, które go używają, ponieważ wiele osób korzysta z GNU sed (jest to implementacja sed w niewbudowanym systemie Linux). Ale OS X sed , podobnie jak inne * BSD sed, nie obsługuje\t
tab, a zamiast tego traktuje to\t
jako ukośnik odwrotnyt
.Istnieje wiele rozwiązań, takich jak:
Użyj dosłownego znaku tabulacji.
Użyj
tr
lub,printf
aby utworzyć znak tabulacji.Użyj składni ciągu bash, umożliwiając ucieczki odwrotnym ukośnikiem .
Użyj Perla, Pythona lub Ruby. Opublikowany fragment kodu Ruby działa.
źródło
...sed
skrypcie (używanych przez-f
opcję) dosłowne znaki tabulacji wydają mi się jedyną możliwością. Podczas edycji tego za pomocą vimaset noexpandtab
ważne jest.tr
technikę tylko wtedy, gdy chcesz, aby twój współpracownik dźgnął cię w twarz podczas czytania twojego scenariusza.sed $'s/<regex>/\t/' file.txt
działa na wstawianie, ale$
wydaje się, że łamie mój skrypt, gdy próbuję dołączyć część wyrażenia regularnego do mojego podstawienia, tj.sed $'s,\(ontology/[0-9]\+\),\t\txxx\1xxx\t\t,'
daje `xxxxxx` z moją oczekiwaną wartością dopasowania zastąpioną przez ``. Czy istnieje odpowiednik\1
przy użyciu składni łańcucha bash? Edycja: w środku xxx <U + 231C> xxx należy umieścić znak Unicode U + 231C.Użyj cytowania specyficznego dla Bash, które pozwala ci używać ciągów jak w C, aby prawdziwy znak tab był przekazywany do sed, a nie sekwencja ucieczki:
źródło
działa dla mnie na OS X i jest to ta sama komenda, której używam przez cały czas w systemie Linux.
źródło
Jak wspomniano, nie wszystkie
sed
implementacje obsługują zapis\t
jako kartę poziomą.Możesz łatwo osiągnąć swoją zamianę za pomocą:
Wykonuje to zamianę in situ, która zachowuje oryginalny plik jako „* .old”. Perl pozwala na stosowanie alternatywnych ograniczników dla klasyki,
/
dzięki czemu wyrażenie jest znacznie bardziej czytelne (tj. Pozbawione syndromu „pochylonej wykałaczki”).+
Mówi jeden lub więcej powtórzeń o charakterze zakładki mają być zastąpione.g
Modyfikator umożliwia globalne zamienniki całej końcu każdej linii.źródło
Możesz także użyć
echo
wewnątrzsed
:sed -i "s/$(echo '\t')//g"
źródło
echo '\t'
po prostu wyświetli się\t
w implementacji niektórych powłokecho
.Jeśli chcesz mieć większą moc
sed
(wsparcie\t
i więcej) niż ten w OS X, zainstaluj GNU sed .źródło
sed
jest problemem. Czy masz powód, by sądzić, że to jest problem? Z przyjemnością zainstalowałbym GNU sed, gdybym miał powód, by sądzić, że to rozwiąże problem, ale wygląda na to, że prawie to wykluczyłem.ruby -pe '$_.gsub!(/\t/," ")' < file.txt
Jeśli wymaganie
bash
lubzsh
powłoka jest w porządku , to jest to najłatwiejsze rozwiązanie, jakie mogę wymyślić:Zauważ jednak, że
echo
flagi (-n
i-e
) są niezdefiniowane w POSIX, więc powłoka zgodna z POSIX nie wymaga zrozumienia tych flag, ale wiele z nich ze względu na kompatybilność.źródło
Dziwi mnie, że nikt nie zasugerował bardzo prostego rozwiązania:
sed -i.bak -E 's/\\\t/ /' file.txt
To powinno wystarczyć.Musisz uciec przed ucieczką (stąd 3 \ s), aby sed mógł zrozumieć, że próbujesz użyć znaku \ t w wyrażeniu regularnym, gdy wszystko zostanie zastąpione ...
źródło
sed
, jeden\
wystarczy, jak ma ucieczki jest konieczne. Problem polega na tym, że BSDsed
nie obsługuje tej składni dla kart.To zadziałało dla mnie.
sed -e 's / [\ t] / / g'
źródło
sed
. Nie tego używa PO.