Dlaczego jest to oznaczone jako oszustwo? To pytanie dotyczy usunięcia powrotu karetki. Domniemany duplikat pytania, do którego prowadzi, dotyczy usunięcia białych znaków i tylko przypadkowo wspomina o powrotach karetki.
Michael Scheper,
1
@MichaelScheper zgodził się i ponownie otworzył.
fedorqui 'SO przestań szkodzić'
Terminologia tutaj jest dziwna. Uniksowy znak końca linii \n(szesnastkowo 0x0A) nazywany jest kłamstwem posuwu (LF); różni się od znaku powrotu karetki (CR) \r(szesnastkowo 0x0D), który jest używany w systemie Windows oraz w wielu protokołach sieciowych jako pierwszy bajt w dwubajtowej sekwencji końca linii CR LF.
To jest sposób na usunięcie wysuwów ze zmiennej w BASH. Inne odpowiedzi niepotrzebnie wywołują dodatkowy proces TR. Przy okazji, ma dodatkową zaletę usuwania spacji końcowych!
ingyhere
1
Zauważ, że usuwa również wewnętrzne spacje z ciągu ... COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n ']}|"zwraca|REBOOT|
Alex Jordan
2
@AlexJordan Tak, jest to pożądana funkcja : możesz usunąć spację, \naby temu zapobiec: COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n']}|"powróci |RE BOOT|.
F. Hauri
2
Jak działa wzór ${COMMAND//[$'\t\r\n']}? Myślałem, ${COMMAND//[\t\r\n]}że po prostu zadziała, ale tak się nie stało. Jaki jest $symbol i jakie pojedyncze cudzysłowy?
haridsv
1
Jeśli chodzi o składnię $ '', jest to cytowanie ANSI C (wspomniane w odpowiedzi wjordans).
chuckx
81
echo "|$COMMAND|"|tr '\n'' '
zamieni znak nowej linii (w POSIX / Unix nie jest to powrót karetki) spacją.
Szczerze mówiąc, pomyślałbym jednak o odejściu od bash na coś bardziej rozsądnego. Lub w pierwszej kolejności unikanie generowania zniekształconych danych.
Hmmm, wygląda na to, że może to być również straszna luka w zabezpieczeniach, w zależności od tego, skąd pochodzą dane.
Data pochodzi z żądania curl, które znajduje się na tym samym serwerze. Jak mam umieścić to w nowej zmiennej? newvar = $ (echo "| $ COMMAND |" | tr '\ n' '')
Matt Leyland
2
Tak. Ale proszę, powiedz mi, że nie zezwalasz arbitralnym osobom na zdalne ponowne uruchomienie serwera bez hasła ...
Czy to nie powoduje zmian w linii? Czy nie powinno być tr -d '\r'zamiast tego?
Izzy
3
Powtórzenie niezakomentowanej zmiennej usuwa wszystkie znaki IFS (domyślnie nowa linia, spacja, tabulator). Więc jeśli masz zamiar to zrobić, powinieneś być świadomy, że wszystkie znaki IFS są odrzucane i nie potrzebujesz tr. Po prostu COMMAND=$(echo $COMMAND)da podobny efekt. Jest to prawdopodobnie diabelski pomiot, który wywołuje nowy proces, ale wciąż jest dość krótki i słodki dla ludzkich oczu, a jeśli masz sekundę lub dwie do stracenia w swoim życiu, możesz zechcieć przyjąć uderzenie :-).
Mike S
Zaktualizowałem pytanie tak, aby brzmiało „wysuw wiersza”, ponieważ jego przykład pokazał, że był to nowy wiersz, a nie powrót karetki. Ta odpowiedź jest nadal poprawna, ale może powinna zostać zaktualizowana, aby powiedzieć „przesunięcie wiersza” zamiast „powrót karetki”?
Benjamin W.,
8
Używając bash:
echo "|${COMMAND/$'\n'}|"
(Zwróć uwagę, że znak kontrolny w tym pytaniu to `` nowa linia '' ( \n), a nie powrót karetki ( \r); ten ostatni miałby wynik REBOOT|w jednym wierszu).
Wzór rozpręża się w celu wytworzenia wzoru jak w rozszerzania nazw. Parametr jest rozwijany, a najdłuższe dopasowanie wzorca do jego wartości jest zastępowane ciągiem . [...] Jeśli łańcuch jest pusty, dopasowania do wzorca są usuwane, a wzorzec / następujący po nim można pominąć.
Używa również konstrukcji $''cytowania ANSI-C, aby określić nowy wiersz jako $'\n'. Bezpośrednie użycie znaku nowej linii również by działało, choć mniej ładne:
Dodanie odpowiedzi, aby pokazać przykład usuwania wielu znaków, w tym \ r używania tr i używania seda. I zilustrowanie za pomocą zrzutu heksowego.
W moim przypadku stwierdziłem, że polecenie kończące się awk print ostatniej pozycji |awk '{print $2}'w linii zawierało znak powrotu karetki \ r oraz cudzysłowy.
Zwykłem sed 's/["\n\r]//g'usuwać zarówno znak powrotu karetki, jak i cudzysłowy.
Mógłbym też użyć tr -d '"\r\n'.
Warto zauważyć, że sed -zjest potrzebny, jeśli ktoś chce usunąć \ n znaki nowego wiersza.
\n
(szesnastkowo 0x0A) nazywany jest kłamstwem posuwu (LF); różni się od znaku powrotu karetki (CR)\r
(szesnastkowo 0x0D), który jest używany w systemie Windows oraz w wielu protokołach sieciowych jako pierwszy bajt w dwubajtowej sekwencji końca linii CR LF.Odpowiedzi:
Pod grzmotnąć, istnieje kilka bashizmów:
tr
Komenda może zostać zastąpiona przez//
bashowymi :Zobacz Rozwijanie parametrów i CYTOWANIE na stronie podręcznika basha:
Dalej...
Zgodnie z zapytaniem @AlexJordan, spowoduje to usunięcie wszystkich określonych znaków. A co, jeśli
$COMMAND
zawierają spacje ...Wkrótce:
Uwaga: grzmotnąćmają
extglob
opcję włączenia (shopt -s extglob
) w celu użycia*(...)
składni.źródło
COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n ']}|"
zwraca|REBOOT|
\n
aby temu zapobiec:COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n']}|"
powróci|RE BOOT|
.${COMMAND//[$'\t\r\n']}
? Myślałem,${COMMAND//[\t\r\n]}
że po prostu zadziała, ale tak się nie stało. Jaki jest$
symbol i jakie pojedyncze cudzysłowy?zamieni znak nowej linii (w POSIX / Unix nie jest to powrót karetki) spacją.
Szczerze mówiąc, pomyślałbym jednak o odejściu od bash na coś bardziej rozsądnego. Lub w pierwszej kolejności unikanie generowania zniekształconych danych.
Hmmm, wygląda na to, że może to być również straszna luka w zabezpieczeniach, w zależności od tego, skąd pochodzą dane.
źródło
tr -d '\n'
tr '\n' ' ' <<< "|$COMMAND|"
zamiastecho ... | ...
"|${COMMAND//$'\n'}|"
Wyczyść zmienną, usuwając wszystkie powroty karetki:
źródło
tr -d '\r'
zamiast tego?tr
. Po prostuCOMMAND=$(echo $COMMAND)
da podobny efekt. Jest to prawdopodobnie diabelski pomiot, który wywołuje nowy proces, ale wciąż jest dość krótki i słodki dla ludzkich oczu, a jeśli masz sekundę lub dwie do stracenia w swoim życiu, możesz zechcieć przyjąć uderzenie :-).Używając
bash
:(Zwróć uwagę, że znak kontrolny w tym pytaniu to `` nowa linia '' (
\n
), a nie powrót karetki (\r
); ten ostatni miałby wynikREBOOT|
w jednym wierszu).Wyjaśnienie
Używa rozszerzenia parametrów powłoki Bash
${parameter/pattern/string}
:Używa również konstrukcji
$''
cytowania ANSI-C, aby określić nowy wiersz jako$'\n'
. Bezpośrednie użycie znaku nowej linii również by działało, choć mniej ładne:Pełny przykład
Lub używając nowych linii:
źródło
Dla mnie zadziałało
echo $testVar | tr "\n" " "
Gdzie testVar zawierał moje dane wyjściowe zmiennej / skryptu
źródło
Dodanie odpowiedzi, aby pokazać przykład usuwania wielu znaków, w tym \ r używania tr i używania seda. I zilustrowanie za pomocą zrzutu heksowego.
W moim przypadku stwierdziłem, że polecenie kończące się awk print ostatniej pozycji
|awk '{print $2}'
w linii zawierało znak powrotu karetki \ r oraz cudzysłowy.Zwykłem
sed 's/["\n\r]//g'
usuwać zarówno znak powrotu karetki, jak i cudzysłowy.Mógłbym też użyć
tr -d '"\r\n'
.Warto zauważyć, że
sed -z
jest potrzebny, jeśli ktoś chce usunąć \ n znaki nowego wiersza.I to jest istotne: co to jest powrót karetki, nowy wiersz i wysuw strony?
źródło
Możesz po prostu użyć
echo -n "|$COMMAND|"
.źródło
Jeśli używasz basha z włączoną opcją extglob, możesz usunąć tylko końcowe białe znaki poprzez:
To daje:
Lub zamień %% na ##, aby zastąpić tylko początkowe białe znaki.
źródło