Bash의 문자열에서 줄 바꿈을 제거하는 방법


110

다음 변수가 있습니다.

echo "|$COMMAND|"

반환하는

|
REBOOT|

첫 줄 바꿈을 어떻게 제거 할 수 있습니까?


7
이것이 왜 속임수로 표시됩니까? 이 질문은 캐리지 리턴 제거에 관한 것입니다. 링크 된 중복 질문은 공백 제거에 관한 것이며 우연히 캐리지 리턴 만 언급합니다.
Michael Scheper 2014 년

1
@MichaelScheper가 동의하고 다시 열었습니다.
fedorqui 'SO stop harming'Apr

여기서 용어는 이상합니다. Unix 줄 끝 문자 \n(16 진수 0x0A)는 거짓말 피드 (LF)라고합니다. \rWindows 및 많은 네트워크 프로토콜에서 2 바이트 줄 끝 시퀀스 CR LF의 첫 번째 바이트로 사용되는 문자 캐리지 리턴 (CR) (16 진수 0x0D)과 는 다릅니다 .
tripleee

답변:


114

아래에 , 몇 가지 바 시즘이 있습니다.

tr명령에 의해 대체 될 수 // bashism :

COMMAND=$'\nREBOOT\r   \n'
echo "|${COMMAND}|"
|
   OOT
|

echo "|${COMMAND//[$'\t\r\n']}|"
|REBOOT   |

echo "|${COMMAND//[$'\t\r\n ']}|"
|REBOOT|

참조 매개 변수 확장인용 배쉬의 매뉴얼 페이지를 :

man -Pless\ +/\/pattern bash
man -Pless\ +/\\\'string\\\' bash

man -Pless\ +/^\\\ *Parameter\\\ Exp bash
man -Pless\ +/^\\\ *QUOTING bash

더욱이...

@AlexJordan의 요청에 따라 지정된 모든 문자 가 표시되지 않습니다 . 그렇다면 $COMMAND공백이 있으면 어떻게 될까요?

COMMAND=$'         \n        RE BOOT      \r           \n'
echo "|$COMMAND|"
|
           BOOT      
|

CLEANED=${COMMAND//[$'\t\r\n']}
echo "|$CLEANED|"
|                 RE BOOT                 |

shopt -q extglob || { echo "Set shell option 'extglob' on.";shopt -s extglob;}

CLEANED=${CLEANED%%*( )}
echo "|$CLEANED|"
|                 RE BOOT|

CLEANED=${CLEANED##*( )}
echo "|$CLEANED|"
|RE BOOT|

곧:

COMMAND=$'         \n        RE BOOT      \r           \n'
CLEANED=${COMMAND//[$'\t\r\n']} && CLEANED=${CLEANED%%*( )}
echo "|${CLEANED##*( )}|"
|RE BOOT|

노트 : extglob옵션 (사용 가능합니다 shopt -s extglob사용하기 위해) *(...)구문.


1
이것은 BASH의 변수에서 줄 바꿈을 제거하는 방법입니다. 다른 답변은 불필요하게 추가 TR 프로세스를 호출합니다. BTW, 그것은 끝 공백을 제거하는 추가 이점이 있습니다!
ingyhere

1
참고 또한 제거하는 것이 내부 ...뿐만 아니라 문자열에서 공백을 COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n ']}|"반환|REBOOT|
알렉스 요르단에게

2
@AlexJordan 예, 원하는 기능입니다 . 다음 \n을 방지하기 위해 공간을 채울 수 있습니다. COMMAND="RE BOOT"; echo "|${COMMAND//[$'\t\r\n']}|"반환 |RE BOOT|됩니다.
F. Hauri 2016 년

2
패턴은 어떻게 작동 ${COMMAND//[$'\t\r\n']}합니까? 나는 ${COMMAND//[\t\r\n]}단순히 작동 할 것이라고 생각 했지만 그렇지 않았습니다. 무엇 $을 위해 너무 작은 따옴표 기호는?
haridsv

1
$``구문과 관련하여 ANSI C 인용 (wjordans 답변에서 언급)입니다.
chuckx

81
echo "|$COMMAND|"|tr '\n' ' '

줄 바꿈 (POSIX / Unix에서는 캐리지 리턴이 아님)을 공백으로 바꿉니다.

솔직히 말해서 bash에서 좀 더 건전한 것으로 전환하는 것에 대해 생각할 것입니다. 또는 처음에이 잘못된 데이터 생성을 피하십시오.

흠, 데이터의 출처에 따라 이것은 끔찍한 보안 구멍이 될 수도 있습니다.


날짜는 동일한 서버에있는 컬 요청에서 비롯됩니다. 새 변수에 어떻게 넣을까요? newvar = $ (echo "| $ COMMAND |"| tr '\ n' '')
Matt Leyland

2
예. 하지만 ... 당신은 임의의 사람이 암호없이 원격으로 서버를 재부팅 할 수 있도록하지 않는 저에게 알려주세요
로빈 그린

31
왜 사용하지 않았 tr -d '\n'에 대한 떨어지는 대신 공백으로 대체
F. 하우리을

3
쓸데없는 파이프를 채찍질하십시오! tr '\n' ' ' <<< "|$COMMAND|"대신 사용echo ... | ...
F. 하우리

12
@ F.Hauri : 또는 쓸모없는 tr :"|${COMMAND//$'\n'}|"
rici

75

모든 캐리지 리턴을 제거하여 변수를 정리하십시오.

COMMAND=$(echo $COMMAND|tr -d '\n')

22
줄 바꿈을 제거하지 않습니까? tr -d '\r'대신 해야하지 않습니까?
Izzy 2014

3
주석 처리되지 않은 변수를 에코하면 모든 IFS 문자 (기본적으로 줄 바꿈, 공백, 탭)가 제거됩니다. 따라서이 작업을 수행하려는 경우 모든 IFS 문자가 삭제되고 tr. 단순히 COMMAND=$(echo $COMMAND)비슷한 효과를 줄 것입니다. 그것은 아마도 새로운 과정을 불러 일으키는 악마의 스폰이지만, 여전히 인간의 눈에는 꽤 짧고 달콤합니다. 그리고 만약 당신이 당신의 인생에서 두 번이나 두 번 여유가 있다면 당신은 기꺼이 맞을 수 있습니다 :-).
Mike S

예제에서 캐리지 리턴이 아닌 줄 바꿈임을 보여 주었기 때문에 "줄 바꿈"이라고 말하도록 질문을 업데이트했습니다. 이 답변은 여전히 ​​정확하지만 "캐리지 리턴"대신 "라인 피드"로 업데이트해야합니까?
Benjamin W.

8

사용 bash:

echo "|${COMMAND/$'\n'}|"

(이 질문의 제어 문자 \n는 캐리지 리턴 ( \r) 이 아니라 '개행' ( )입니다. 후자는 REBOOT|한 줄에 출력 됩니다.)

설명

Bash Shell 매개 변수 확장 사용 ${parameter/pattern/string} :

패턴은 단지 파일 이름 확장에서 같은 패턴을 생성하기 위해 확장된다. 매개 변수 가 확장되고 해당 값에 대한 가장 긴 패턴 일치 가 string 으로 대체됩니다 . [...] 문자열 이 null 인 경우 일치하는 패턴 은 삭제되고 / 다음 패턴 은 생략 될 수 있습니다.

또한 $'' ANSI-C 인용 구문을 사용하여 개행을 $'\n'. 줄 바꿈을 직접 사용하는 것도 좋지만 덜 예쁘게 작동합니다.

echo "|${COMMAND/
}|"

전체 예

#!/bin/bash
COMMAND="$'\n'REBOOT"
echo "|${COMMAND/$'\n'}|"
# Outputs |REBOOT|

또는 줄 바꿈 사용 :

#!/bin/bash
COMMAND="
REBOOT"
echo "|${COMMAND/
}|"
# Outputs |REBOOT|

6

나를 위해 일한 것은 echo $testVar | tr "\n" " "

testVar에 내 변수 / 스크립트 출력이 포함 된 위치


4

tr을 사용하고 sed를 사용하여 \ r을 포함하여 여러 문자를 제거하는 예를 보여주기 위해 답변을 추가합니다. 그리고 hexdump를 사용하여 설명합니다.

제 경우에는 마지막 항목의 awk 인쇄로 끝나는 명령이 |awk '{print $2}' 에는 줄 에 캐리지 리턴 \ r과 따옴표가 포함되어 .

나는 사용했다 sed 's/["\n\r]//g' 캐리지 리턴과 따옴표를 모두 제거 할 수 있습니다.

나는 또한 사용할 수 있었다 tr -d '"\r\n' .

sed -z줄 바꿈 문자를 제거하려면 \ n 주목할 점이 필요합니다.

$ COMMAND=$'\n"REBOOT"\r   \n'

$ echo "$COMMAND" |hexdump -C
00000000  0a 22 52 45 42 4f 4f 54  22 0d 20 20 20 0a 0a     |."REBOOT".   ..|

$ echo "$COMMAND" |tr -d '"\r\n' |hexdump -C
00000000  52 45 42 4f 4f 54 20 20  20                       |REBOOT   |

$ echo "$COMMAND" |sed 's/["\n\r]//g' |hexdump -C
00000000  0a 52 45 42 4f 4f 54 20  20 20 0a 0a              |.REBOOT   ..|

$ echo "$COMMAND" |sed -z 's/["\n\r]//g' |hexdump -C
00000000  52 45 42 4f 4f 54 20 20  20                       |REBOOT   |

그리고 이것은 관련이 있습니다. 캐리지 리턴, 줄 바꿈 및 용지 공급이란 무엇입니까?

  • CR == \ r == 0x0d
  • LF == \ n == 0x0a


2

extglob 옵션이 활성화 된 상태에서 bash를 사용하는 경우 다음을 통해 후행 공백 만 제거 할 수 있습니다.

shopt -s extglob
COMMAND=$'\nRE BOOT\r   \n'
echo "|${COMMAND%%*([$'\t\r\n '])}|"

결과는 다음과 같습니다.

|
RE BOOT|

또는 선행 공백 만 바꾸려면 %%를 ##으로 바꾸십시오.


1
이것은 도커 명령에서 얻은 이상한 출력으로 매력처럼 작동했습니다. 대단히 감사합니다!
develCuy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.