출력의 각 줄에서 선행 및 후행 공백과 탭을 모두 제거하고 싶습니다.
다음과 같은 간단한 도구가 있습니까? trim
출력을 다음으로 파이프 할 수 있습니까?
예제 파일 :
test space at back test space at front TAB at end TAB at front sequence of some space in the middle some empty lines with differing TABS and spaces: test space at both ends
댓글
- 여기에서 줄 바꿈 제거 솔루션을 찾는 사람에게는 이는 다른 문제입니다. 정의에 따라 개행은 새로운 텍스트 행을 만듭니다. 따라서 텍스트 행에는 개행이 포함될 수 없습니다. 질문하고 싶은 질문은 문자열의 시작 또는 끝에서 줄 바꿈을 제거하는 방법입니다 : stackoverflow.com/questions/369758 또는 공백을 제거하는 방법 공백 만있는 줄 또는 줄 : serverfault.com/questions/252921
답변
awk "{$1=$1;print}"
또는 더 짧음 :
awk "{$1=$1};1"
행간 및 후행 공백 또는 탭 문자 1 및 탭 시퀀스 짜기 그리고 공백을 하나의 공간으로 만듭니다.
필드 중 하나에 무언가를 할당하면 awk
가 전체 레코드를 다시 작성하기 때문에 작동합니다. (print
에 의해 인쇄 됨) 모든 필드 ($1
, …, $NF
) OFS
(기본적으로 공백).
1 (및 기타 공백 문자 로케일 및 awk
구현에 따라 다름)
댓글
- 세미콜론 두 번째 예는 불필요합니다. 사용 가능 :
awk '{$1=$1}1'
- @Brian, 아니요,
;
는 표준 awk 구문에 필요합니다. - 흥미로운 … gawk, mawk 및 OS X ‘ s awk에서는 세미콜론이 지원되지 않습니다. (적어도 내 버전 (각각 1.2, 4.1.1 및 20070501)의 경우)
- 이 접근 방식에서 ‘가 마음에 들지 않는 유일한 점은 줄 내에서 반복되는 공백이 없어집니다. 예 :
echo -e 'foo \t bar' | awk '{$1=$1};1'
-
echo ' hello ' | xargs
답변
GNU sed
를 사용하는 경우 다음과 같이 명령을 압축 할 수 있습니다.
p>
$ sed "s/^[ \t]*//;s/[ \t]*$//" < file
예
다음은 실행중인 위 명령입니다.
$ echo -e " \t blahblah \t " | sed "s/^[ \t]*//;s/[ \t]*$//" blahblah
hexdump
를 사용하여 sed
명령이 원하는 문자를 올바르게 제거하는지 확인할 수 있습니다.
$ echo -e " \t blahblah \t " | sed "s/^[ \t]*//;s/[ \t]*$//" | hexdump -C 00000000 62 6c 61 68 62 6c 61 68 0a |blahblah.| 00000009
문자 클래스
문자 그대로 다음과 같이 세트를 나열하는 대신 문자 클래스 이름을 사용할 수도 있습니다. [ \t]
:
$ sed "s/^[[:blank:]]*//;s/[[:blank:]]*$//" < file
예
$ echo -e " \t blahblah \t " | sed "s/^[[:blank:]]*//;s/[[:blank:]]*$//"
정규 표현식을 사용하는 대부분의 GNU 도구 ssions (정규식)는 이러한 클래스를 지원합니다 (여기서는 ASCII 기반 시스템의 일반적인 C 로케일에 해당하는 클래스 만 있음).
[[:alnum:]] - [A-Za-z0-9] Alphanumeric characters [[:alpha:]] - [A-Za-z] Alphabetic characters [[:blank:]] - [ \t] Space or tab characters only [[:cntrl:]] - [\x00-\x1F\x7F] Control characters [[:digit:]] - [0-9] Numeric characters [[:graph:]] - [!-~] Printable and visible characters [[:lower:]] - [a-z] Lower-case alphabetic characters [[:print:]] - [ -~] Printable (non-Control) characters [[:punct:]] - [!-/:-@[-`{-~] Punctuation characters [[:space:]] - [ \t\v\f\n\r] All whitespace chars [[:upper:]] - [A-Z] Upper-case alphabetic characters [[:xdigit:]] - [0-9a-fA-F] Hexadecimal digit characters
사용 리터럴 세트 대신 이것들은 항상 공간 낭비처럼 보이지만, “코드가 이식 가능하거나 대체 문자 세트를 처리해야하는 경우 (국제를 생각하십시오)”대신 클래스 이름을 사용하고 싶을 것입니다. .
참조
댓글
-
[[:space:]]
는 다음의[ \t]
와 동일하지 않습니다. 일반적인 경우 (유니 코드 등).[[:space:]]
는 아마도 훨씬 더 느릴 것입니다 (유니 코드에는' '
및 ). 다른 모든 제품도 마찬가지입니다. -
sed 's/^[ \t]*//'
는 이식 할 수 없습니다. 실제로 POSIX에서는 공백, 백 슬래시 또는t
문자의 시퀀스를 제거해야하며, ‘ GNUsed
는POSIXLY_CORRECT
가 환경에있을 때도 수행합니다. - 줄 바꿈 문자를 자르려면 어떻게해야합니까? ‘ \ n \ n text \ n \ n ‘
- 저는 sed 솔루션을 좋아합니다. awk 솔루션에서와 같이 다른 부작용. 첫 번째 변형은 OSX jsut에서 bash에서 시도했을 때 작동하지 않지만 문자 클래스 버전은 작동합니다.
sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//'
- @EugeneBiryukov 원본 게시물
Answer
인수가없는 xargs는 그렇게합니다.
예 :
trimmed_string=$(echo "no_trimmed_string" | xargs)
댓글
- 또한 질문에서 요청되지 않은 줄
- @roaima-사실이지만 수락 된 답변은 공백을 꽉 쥐기도합니다 (질문에서 요청되지 않음). 여기서 진짜 문제는 입력에 백 슬래시와 작은 따옴표가 포함되어 있으면
xargs
가 전달되지 않는다는 것입니다. - @don_crissti ‘는 허용 된 답변이 질문에 대한 올바른 답변을 의미하지는 않습니다. 그러나이 경우에는 ‘주의 사항으로 표시되지 않았고 허용 된 답변에서는 표시되지 않았습니다. 저는 ‘ 미래의 독자와 관련된 ‘ 사실을 강조했습니다.
- 또한 작은 따옴표, 큰 따옴표, 백 슬래시 문자를 끊습니다. 또한 하나 이상의
echo
호출을 실행합니다. 일부 에코 구현은 옵션 및 / 또는 백 슬래시도 처리합니다 … 이는 한 줄 입력에서만 작동합니다.
Answer
Stéphane Chazelas 가 수락 된 답변에서 제안했듯이 이제
스크립트를 만들 수 있습니다. /usr/local/bin/trim
:
#!/bin/bash awk "{$1=$1};1"
파일 실행 권한을 부여합니다.
chmod +x /usr/local/bin/trim
이제 모든 출력을 trim
에 전달할 수 있습니다. 예를 들면 다음과 같습니다.
cat file | trim
(아래 주석 : 이전에 사용한 적이 있음 : while read i; do echo "$i"; done
도 잘 작동하지만 성능이 떨어짐)
댓글
- 파일이 크거나 백 슬래시가 포함되어 있으면 행운을 빕니다.
- @don_crissti : 댓글을 조금 더 줄 수 있나요? 대용량 파일에 더 적합하며 파일에 백 슬래시가 포함 된 경우 솔루션을 어떻게 수정할 수 있습니까?
- ‘
while read -r line
를 사용하여 백 슬래시를 유지하고 그래도 … . 대용량 파일 / 속도에 관해서는 실제로 최악의 솔루션을 선택했습니다. 저는 ‘ 더 나쁜 것이 없다고 생각합니다 ‘. 속도 벤치 마크에 대한 링크를 추가 한 마지막 답변에 대한 내 의견을 포함하여 왜 쉘 루프를 사용하여 텍스트를 처리하지 않습니까? 에 대한 답변을 참조하십시오. 여기의sed
답변은 완벽하게 괜찮은 IMO이며read
보다 훨씬 낫습니다. - 또한 별칭을 추가 할 수 있습니다. / etc / profile (또는 ~ / .bashrc 또는 ~ / .zshrc 등 …) 별칭 trim = ” awk ‘ { \ $ 1 = \ $ 1}; 1 ‘ ”
-
bash
,#! /usr/bin/awk -f
{$1=$1};1
로 만들 수 있습니다. (=
문자가 포함 된 파일 이름에주의하십시오)
답변
줄을 변수로 저장하는 경우 bash를 사용하여 작업을 수행 할 수 있습니다.
문자열에서 선행 공백을 제거합니다.
shopt -s extglob echo ${text##+([[:space:]])}
문자열에서 후행 공백 제거 :
shopt -s extglob echo ${text%%+([[:space:]])}
문자열에서 모든 공백 제거 :
echo ${text//[[:space:]]}
주석
- 문자열에서 모든 공백을 제거하는 것은 (문제에서와 같이) 선행 및 후행 공백을 모두 제거하는 것과 다릅니다.
- 최고의 솔루션-bash 내장 만 필요하고 외부 프로세스 포크가 필요하지 않습니다.
- 좋습니다. 스크립트는 ‘ 외부 프로그램 (예 : awk 또는 sed)을 가져올 필요가 없으면 훨씬 더 빠르게 실행됩니다. 이것은 ksh의 ” 최신 ” (93u +) 버전에서도 작동합니다.
답변
sed -e "s/^[[:space:]]*//" -e "s/[[:space:]]*$//"
셸 변수로 줄을 읽는 경우 read
는 달리 지시하지 않는 한 이미 그렇게합니다.
댓글
- i
- @rubo 귀하의 예에서 인용되지 않은 변수도 쉘에 의해 재 처리됩니다.
echo "$i"
를 사용하여read
read
에 대해> +1입니다. 따라서 읽는 동안 파이프로 연결하면 작동합니다. cat file | while read i; do echo $i; done
의 실제 효과를 확인하십시오. / ul>
Answer
“파이프”도구 덕분에 주어진 줄에서 모든 선행 및 후행 공백을 제거하려면 이러한 차이는 입력 줄의 단어 사이의 공백과 관련이 있습니다. 예상되는 b에 따라 ehaviour, 당신은 당신의 선택을 할 것입니다.
예
차이점을 설명하기 위해 다음 더미 입력 줄을 살펴 보겠습니다.
" \t A \tB\tC \t "
tr
$ echo -e " \t A \tB\tC \t " | tr -d "[:blank:]" ABC
tr
는 정말 간단한 명령입니다. 이 경우 공백 또는 표 문자를 삭제합니다.
awk
$ echo -e " \t A \tB\tC \t " | awk "{$1=$1};1" A B C
awk
는 선행 및 후미 공백을 삭제하고 단어 사이의 모든 공백을 단일 공백으로 압축합니다.
sed
$ echo -e " \t A \tB\tC \t " | sed "s/^[ \t]*//;s/[ \t]*$//" A B C
이 경우 sed
는 단어 사이의 공백을 건드리지 않고 앞뒤 공백을 삭제합니다.
참고 :
한 줄에 한 단어의 경우 tr
가 작업을 수행합니다.
댓글
- 이 중 어느 것도 후행 / 선행 줄 바꿈을 잘라 내지 않습니다.
- (때때로 예상치 못한) 출력이있는 솔루션 목록의 경우 +1입니다.
- @ user61382 다소 늦었지만 원본 게시물에 대한 내 의견을 참조하십시오.
- @highmaintenance : 령에 [: blank :] 대신
[:space:]
를 사용합니다. div id = “dd2bc4a516”>
(예 :... | tr -d [:space:]
), 줄 바꿈도 제거합니다. (참조 :man tr
)
답변
sed는 이를위한 훌륭한 도구 :
# substitute ("s/") sed "s/^[[:blank:]]*//; # parts of lines that start ("^") with a space/tab s/[[:blank:]]*$//" # or end ("$") with a space/tab # with nothing (/)
텍스트에 파이핑 (예 :
또는 sed
가 GNU 인 경우 “인라인”으로 작동합니다.
sed -i "s/..." file
하지만 이러한 방식으로 소스를 변경하는 것은 “위험”합니다. 제대로 작동하지 않는 경우 (또는 작동하는 경우에도) 복구 할 수 없으므로 먼저 백업 (또는 -i.bak
일부 BSD sed
s로 이식 할 수 있다는 이점도 있습니다.
Answer
한눈에 이해할 수있는 답변 :
#!/usr/bin/env python3 import sys for line in sys.stdin: print(line.strip())
보너스 : 교체 str.strip([chars])
는 필요에 따라 .lstrip()
또는 .rstrip()
를 트리밍하거나 사용합니다.
rubo77 “sa처럼 nswer , 스크립트 /usr/local/bin/trim
로 저장하고 chmod +x
로 권한을 부여합니다.
Answer
자르려는 문자열이 짧고 연속적이거나 연속적이라면 매개 변수로 전달하면됩니다. 모든 bash 함수에 :
trim(){ echo $@ } a=" some random string " echo ">>`trim $a`<<" Output >>some random string<<
Answer
다음을 사용하여이 쉘 함수를 작성했습니다. awk
awkcliptor(){ awk -e "BEGIN{ RS="^$" } {gsub(/^[\n\t ]*|[\n\t ]*$/,"");print ;exit}" "$1" ; }
BEGIN{ RS="^$" }
:
세트 레코드 파싱을 시작하기 전에
구분 기호를 없음으로 즉, 전체 입력을
단일 레코드로 취급
gsub(this,that)
:
이 정규식을 해당 문자열로 대체
/^[\n\t ]*|[\n\t ]*$/
:
해당 문자열의 모든 사전 개행 공백 및 탭 클래스를 포착하거나
개행 공백 및 탭 클래스를 게시하고
빈 문자열로 대체합니다.
print;exit
: 그런 다음 인쇄 및 종료
"$1"
:
함수의 첫 번째 인수를 awk로
처리
사용 방법 :
위 코드를 복사하고 셸에 붙여 넣은 다음 입력하여
정의
그런 다음 awkcliptor를 입력 파일로 첫 번째 인수가있는 명령으로 사용할 수 있습니다.
샘플 사용 :
echo " ggggg " > a_file awkcliptor a_file
출력 :
ggggg
또는
echo -e "\n ggggg \n\n "|awkcliptor
출력 :
ggggg
댓글
-
awk '{$1=$1};1'
의 차이점을 설명해 주시겠습니까?
Answer
모호한 sed 구문을 기억할 수있을만큼 뇌에 충분한 공간이없는 사람들은 문자열을 뒤집습니다. , 공백 구분 기호로 첫 번째 필드를 잘라 내고 다시 되돌립니다.
cat file | rev | cut -d" " -f1 | rev
댓글
- 각 줄 앞에 공백이 두 개 이상없고 한 줄에 단어가 두 개 이하인 경우에만 작동합니다.
답변
trimpy () { python3 -c "import sys for line in sys.stdin: print(line.strip())" } trimsed () { gsed -e "s/^[[:space:]]*//" -e "s/[[:space:]]*$//" } trimzsh () { local out="$(</dev/stdin)" [[ "$out" =~ "^\s*(.*\S)\s*$" ]] && out="$match[1]" || out="" print -nr -- "$out" } # example usage echo " hi " | trimpy
보너스 : str.strip([chars])
를 임의의 문자로 대체하여 또는 .rstrip()
필요에 따라.
답변
번역 명령이 작동합니다.
cat file | tr -d [:blank:]
설명
- 이 명령은 를 제거하므로 올바르지 않습니다. 파일의 모든 공백, 선행 / 후행 공백이 아닙니다.
- @BrianRedbeard 맞습니다. 이것은 공백이없는 모 놀리 식 문자열에 대한 유용한 답변입니다.
답변
bash 예 :
alias trim="awk "{\$1=\$1};1""
사용 :
echo -e " hello\t\tkitty " | trim | hexdump -C
결과 :
00000000 68 65 6c 6c 6f 20 6b 69 74 74 79 0a |hello kitty.| 0000000c
댓글
-
awk '{$1=$1};1'
답변은 오래 전에 제공되었습니다. 별명을 만드는 아이디어는 거의 오래 전에 의견에서 제안되었습니다. 예, 다른 사람의 댓글을 받아 답으로 바꿀 수 있습니다. 그러나 만약 그렇게한다면, 당신은 이전에 아이디어를 게시 한 사람들에게 크레딧을 주어야합니다. 그리고 이것은 받아 들여진 대답의 아주 사소한 확장이므로 귀찮게 할 가치가 없습니다. - 아이디어는 별칭을 만드는 것이 었습니다. ‘ 이전에는 그 답을 본 적이 없습니다.
- 그리고 스택의 두 번째 항목 : ” 의견을 보내 주셔서 감사합니다! 평판이 15 개 미만인 사람의 투표는 기록되지만 공개적으로 표시되는 게시물 점수는 변경되지 않습니다. ”