Bash 변수에서 공백을 잘라내는 방법
다음 코드를 가진 셸 스크립트가 있습니다.
var=`hg st -R "$path"`
if [ -n "$var" ]; then
echo $var
fi
, 는 항상 왜냐하면 조건부호는 조건부호이기 때문입니다.hg st
는 항상 최소 1개의 줄바꿈 문자를 인쇄합니다.
- 빈 공간을 제거할 수 있는 간단한 방법이 있나요?
$var
것)trim()
(PHP)로 표시됩니까?
또는
- 이 문제에 대한 표준적인 대처 방법이 있습니까?
SED나 AWK를 사용할 수 있지만, 이 문제에 대한 보다 우아한 해결책이 있다고 생각합니다.
간단한 답은 다음과 같습니다.
echo " lol " | xargs
Xargs가 손질해 줄 거예요.파라미터 없이 명령어/프로그램 하나면 쉽게 문자열이 반환됩니다!
모든 내부 것은 때문에: 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 맞다."foo bar"
, stays대 、 하 stays 、 하 stays stays stays stays stays stays stays stays stays stays stays stays stays stays stays stays stays stays stays stays가 되지 ."foobar"
, 「 」 「 」 「 」 「 」 「 」"foo bar"
될 것이다"foo bar"
게다가 행의 끝의 문자는 삭제되지 않습니다.
선행, 후행 및 중간 공백을 포함하는 변수를 정의합니다.
FOO=' test test test '
echo -e "FOO='${FOO}'"
# > FOO=' test test test '
echo -e "length(FOO)==${#FOO}"
# > length(FOO)==16
삭제 (「」로 )[:space:]
tr
FOO=' test test test '
FOO_NO_WHITESPACE="$(echo -e "${FOO}" | tr -d '[:space:]')"
echo -e "FOO_NO_WHITESPACE='${FOO_NO_WHITESPACE}'"
# > FOO_NO_WHITESPACE='testtesttest'
echo -e "length(FOO_NO_WHITESPACE)==${#FOO_NO_WHITESPACE}"
# > length(FOO_NO_WHITESPACE)==12
선행 공백만 삭제하는 방법:
FOO=' test test test '
FOO_NO_LEAD_SPACE="$(echo -e "${FOO}" | sed -e 's/^[[:space:]]*//')"
echo -e "FOO_NO_LEAD_SPACE='${FOO_NO_LEAD_SPACE}'"
# > FOO_NO_LEAD_SPACE='test test test '
echo -e "length(FOO_NO_LEAD_SPACE)==${#FOO_NO_LEAD_SPACE}"
# > length(FOO_NO_LEAD_SPACE)==15
후행 공백만 제거하는 방법:
FOO=' test test test '
FOO_NO_TRAIL_SPACE="$(echo -e "${FOO}" | sed -e 's/[[:space:]]*$//')"
echo -e "FOO_NO_TRAIL_SPACE='${FOO_NO_TRAIL_SPACE}'"
# > FOO_NO_TRAIL_SPACE=' test test test'
echo -e "length(FOO_NO_TRAIL_SPACE)==${#FOO_NO_TRAIL_SPACE}"
# > length(FOO_NO_TRAIL_SPACE)==15
스페이스를 the chain the space---sed
s:
FOO=' test test test '
FOO_NO_EXTERNAL_SPACE="$(echo -e "${FOO}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
echo -e "FOO_NO_EXTERNAL_SPACE='${FOO_NO_EXTERNAL_SPACE}'"
# > FOO_NO_EXTERNAL_SPACE='test test test'
echo -e "length(FOO_NO_EXTERNAL_SPACE)==${#FOO_NO_EXTERNAL_SPACE}"
# > length(FOO_NO_EXTERNAL_SPACE)==14
bash를 대체할 수 .echo -e "${FOO}" | sed ...
sed ... <<<${FOO}
( 공공공 ( ( ( ( 。
FOO_NO_TRAIL_SPACE="$(sed -e 's/[[:space:]]*$//' <<<${FOO})"
와일드카드라고 불리는 Bash 빌트인만을 사용하는 솔루션이 있습니다.
var=" abc "
# remove leading whitespace characters
var="${var#"${var%%[![:space:]]*}"}"
# remove trailing whitespace characters
var="${var%"${var##*[![:space:]]}"}"
printf '%s' "===$var==="
다음은 함수로 묶은 동일한 내용입니다.
trim() {
local var="$*"
# remove leading whitespace characters
var="${var#"${var%%[![:space:]]*}"}"
# remove trailing whitespace characters
var="${var%"${var##*[![:space:]]}"}"
printf '%s' "$var"
}
잘라낼 문자열을 따옴표로 묶은 형식으로 전달합니다. 예:
trim " abc "
이 솔루션의 장점은 모든 POSIX 준거 셸에서 작동한다는 것입니다.
언급
- Bash 변수에서 선행 및 후행 공백 제거(원본 원본)
문자열의 선두와 말미에서 모든 공백을 삭제하려면(줄 끝 문자 포함) 다음 절차를 수행합니다.
echo $variable | xargs echo -n
이렇게 하면 중복된 공간도 제거됩니다.
echo " this string has a lot of spaces " | xargs echo -n
Produces: 'this string has a lot of spaces'
Bash에는 파라미터 확장이라고 불리는 기능이 있습니다.이 기능을 통해 이른바 패턴에 기초한 문자열 치환이 가능합니다(패턴은 정규 표현과 비슷하지만 근본적인 차이와 제한이 있습니다).[원래 대사의 Bash는 규칙적인 표현이 있지만 잘 숨겨져 있습니다]
다음은 변수 값에서 모든 공백을 제거하는 방법을 보여 줍니다(내부에서도 마찬가지).
$ var='abc def'
$ echo "$var"
abc def
# Note: flussence's original expression was "${var/ /}", which only replaced the *first* space char., wherever it appeared.
$ echo -n "${var//[[:space:]]/}"
abcdef
선행 공간 하나와 후행 공간 하나를 제거합니다.
trim()
{
local trimmed="$1"
# Strip leading space.
trimmed="${trimmed## }"
# Strip trailing space.
trimmed="${trimmed%% }"
echo "$trimmed"
}
예를 들어 다음과 같습니다.
test1="$(trim " one leading")"
test2="$(trim "one trailing ")"
test3="$(trim " one leading and one trailing ")"
echo "'$test1', '$test2', '$test3'"
출력:
'one leading', 'one trailing', 'one leading and one trailing'
선행 및 후행 공백을 모두 제거합니다.
trim()
{
local trimmed="$1"
# Strip leading spaces.
while [[ $trimmed == ' '* ]]; do
trimmed="${trimmed## }"
done
# Strip trailing spaces.
while [[ $trimmed == *' ' ]]; do
trimmed="${trimmed%% }"
done
echo "$trimmed"
}
예를 들어 다음과 같습니다.
test4="$(trim " two leading")"
test5="$(trim "two trailing ")"
test6="$(trim " two leading and two trailing ")"
echo "'$test4', '$test5', '$test6'"
출력:
'two leading', 'two trailing', 'two leading and two trailing'
Globing에 대한 Bash Guide 섹션에서
매개 변수 확장에서 extglob을 사용하려면
#Turn on extended globbing
shopt -s extglob
#Trim leading and trailing whitespace from a variable
x=${x##+([[:space:]])}; x=${x%%+([[:space:]])}
#Turn off extended globbing
shopt -u extglob
함수에 포함된 동일한 기능을 다음에 나타냅니다(참고: 함수에 전달된 입력 문자열을 인용해야 합니다).
trim() {
# Determine if 'extglob' is currently on.
local extglobWasOff=1
shopt extglob >/dev/null && extglobWasOff=0
(( extglobWasOff )) && shopt -s extglob # Turn 'extglob' on, if currently turned off.
# Trim leading and trailing whitespace
local var=$1
var=${var##+([[:space:]])}
var=${var%%+([[:space:]])}
(( extglobWasOff )) && shopt -u extglob # If 'extglob' was off before, turn it back off.
echo -n "$var" # Output trimmed string.
}
사용방법:
string=" abc def ghi ";
#need to quote input-string to preserve internal white-space if any
trimmed=$(trim "$string");
echo "$trimmed";
서브셸에서 실행하도록 함수를 변경하면 extglob에 대해 현재 셸 옵션을 검사할 필요가 없습니다.현재 셸에 영향을 주지 않고 설정할 수 있습니다.이것에 의해, 기능이 큰폭으로 심플화됩니다.또한 위치 매개변수를 "제자리"로 업데이트하므로 로컬 변수가 필요하지 않습니다.
trim() {
shopt -s extglob
set -- "${1##+([[:space:]])}"
printf "%s" "${1%%+([[:space:]])}"
}
따라서:
$ s=$'\t\n \r\tfoo '
$ shopt -u extglob
$ shopt extglob
extglob off
$ printf ">%q<\n" "$s" "$(trim "$s")"
>$'\t\n \r\tfoo '<
>foo<
$ shopt extglob
extglob off
수 .echo
:
foo=" qsdqsd qsdqs q qs "
# Not trimmed
echo \'$foo\'
# Trim
foo=`echo $foo`
# Trimmed
echo \'$foo\'
난 항상 세드로 해왔어
var=`hg st -R "$path" | sed -e 's/ *$//'`
좀 더 우아한 해결책이 있다면 누가 올려줬으면 좋겠어요.
유효하게 되어 경우(Bash의 경우).shopt -s extglob
을하면 됩니다
{trimmed##*( )}
임의의 양의 선행 공간을 제거합니다.
은 삭제가 합니다.tr
:
var=`hg st -R "$path" | tr -d '\n'`
if [ -n $var ]; then
echo $var
done
# Trim whitespace from both ends of specified parameter
trim () {
read -rd '' $1 <<<"${!1}"
}
# Unit test for trim()
test_trim () {
local foo="$1"
trim foo
test "$foo" = "$2"
}
test_trim hey hey &&
test_trim ' hey' hey &&
test_trim 'ho ' ho &&
test_trim 'hey ho' 'hey ho' &&
test_trim ' hey ho ' 'hey ho' &&
test_trim $'\n\n\t hey\n\t ho \t\n' $'hey\n\t ho' &&
test_trim $'\n' '' &&
test_trim '\n' '\n' &&
echo passed
많은 답변이 있지만, 저는 제가 방금 쓴 대본이 언급될 가치가 있다고 생각합니다.
- 셸 bash/shells/shellsbox 쉘에서 성공적으로 테스트되었습니다.
- 극히 작다
- 외부 명령어에 의존하지 않기 때문에 (-> 고속 및 저자원 사용률)을 분할할 필요가 없습니다.
- 예상대로 동작합니다.
- 모든 공백과 탭을 처음부터 끝까지 제거하지만 그 이상은 제거하지 않습니다.
- 중요: 문자열 중간에서 아무것도 삭제하지 않습니다(다른 많은 답변이 삭제됨). 심지어 줄바꿈도 그대로 남습니다.
- : 페셜 :
"$*"
이렇게 첫 번째 때는 1번 인수로만 다듬어서 출력하려면 '1번'을 사용하세요."$1"
대신에 - 파일 이름 패턴 일치 등에 문제가 없는 경우
스크립트:
trim() {
local s2 s="$*"
until s2="${s#[[:space:]]}"; [ "$s2" = "$s" ]; do s="$s2"; done
until s2="${s%[[:space:]]}"; [ "$s2" = "$s" ]; do s="$s2"; done
echo "$s"
}
사용방법:
mystring=" here is
something "
mystring=$(trim "$mystring")
echo ">$mystring<"
출력:
>here is
something<
내가 한 일은 완벽하고 간단한 거야
the_string=" test"
the_string=`echo $the_string`
echo "$the_string"
출력:
test
「 」가 shopt -s extglob
이네이블의경우,다음은정확한솔루션입니다.
이 방법은 효과가 있었습니다.
text=" trim my edges "
trimmed=$text
trimmed=${trimmed##+( )} #Remove longest matching series of spaces from the front
trimmed=${trimmed%%+( )} #Remove longest matching series of spaces from the back
echo "<$trimmed>" #Adding angle braces just to make it easier to confirm that all spaces are removed
#Result
<trim my edges>
동일한 결과를 얻기 위해 더 적은 줄에 배치하려면:
text=" trim my edges "
trimmed=${${text##+( )}%%+( )}
# Strip leading and trailing white space (new line inclusive).
trim(){
[[ "$1" =~ [^[:space:]](.*[^[:space:]])? ]]
printf "%s" "$BASH_REMATCH"
}
또는
# Strip leading white space (new line inclusive).
ltrim(){
[[ "$1" =~ [^[:space:]].* ]]
printf "%s" "$BASH_REMATCH"
}
# Strip trailing white space (new line inclusive).
rtrim(){
[[ "$1" =~ .*[^[:space:]] ]]
printf "%s" "$BASH_REMATCH"
}
# Strip leading and trailing white space (new line inclusive).
trim(){
printf "%s" "$(rtrim "$(ltrim "$1")")"
}
또는
# Strip leading and trailing specified characters. ex: str=$(trim "$str" $'\n a')
trim(){
if [ "$2" ]; then
trim_chrs="$2"
else
trim_chrs="[:space:]"
fi
[[ "$1" =~ ^["$trim_chrs"]*(.*[^"$trim_chrs"])["$trim_chrs"]*$ ]]
printf "%s" "${BASH_REMATCH[1]}"
}
또는
# Strip leading specified characters. ex: str=$(ltrim "$str" $'\n a')
ltrim(){
if [ "$2" ]; then
trim_chrs="$2"
else
trim_chrs="[:space:]"
fi
[[ "$1" =~ ^["$trim_chrs"]*(.*[^"$trim_chrs"]) ]]
printf "%s" "${BASH_REMATCH[1]}"
}
# Strip trailing specified characters. ex: str=$(rtrim "$str" $'\n a')
rtrim(){
if [ "$2" ]; then
trim_chrs="$2"
else
trim_chrs="[:space:]"
fi
[[ "$1" =~ ^(.*[^"$trim_chrs"])["$trim_chrs"]*$ ]]
printf "%s" "${BASH_REMATCH[1]}"
}
# Strip leading and trailing specified characters. ex: str=$(trim "$str" $'\n a')
trim(){
printf "%s" "$(rtrim "$(ltrim "$1" "$2")" "$2")"
}
또는
모스킷의 영혼 파괴를 바탕으로...
# Strip leading and trailing white space (new line inclusive).
trim(){
printf "%s" "`expr "$1" : "^[[:space:]]*\(.*[^[:space:]]\)[[:space:]]*$"`"
}
또는
# Strip leading white space (new line inclusive).
ltrim(){
printf "%s" "`expr "$1" : "^[[:space:]]*\(.*[^[:space:]]\)"`"
}
# Strip trailing white space (new line inclusive).
rtrim(){
printf "%s" "`expr "$1" : "^\(.*[^[:space:]]\)[[:space:]]*$"`"
}
# Strip leading and trailing white space (new line inclusive).
trim(){
printf "%s" "$(rtrim "$(ltrim "$1")")"
}
AWK 사용:
echo $var | awk '{gsub(/^ +| +$/,"")}1'
사용 tr
예를 들어, git 저장소에서 변경된 파일 수를 반환합니다. 이치노
MYVAR=`git ls-files -m|wc -l|tr -d ' '`
그러면 String에서 모든 공백이 제거됩니다.
VAR2="${VAR2//[[:space:]]/}"
/
첫 번째 오카렌스를 대체하고//
문자열에 공백이 모두 표시됩니다.즉, 모든 공백이 아무것도 아닌 것으로 대체됩니다.
SED를 사용하면 됩니다.
function trim
{
echo "$1" | sed -n '1h;1!H;${;g;s/^[ \t]*//g;s/[ \t]*$//g;p;}'
}
a) 한 줄 문자열에서의 사용 예
string=' wordA wordB wordC wordD '
trimmed=$( trim "$string" )
echo "GIVEN STRING: |$string|"
echo "TRIMMED STRING: |$trimmed|"
출력:
GIVEN STRING: | wordA wordB wordC wordD |
TRIMMED STRING: |wordA wordB wordC wordD|
b) 복수행 문자열에서의 사용 예
string=' wordA
>wordB<
wordC '
trimmed=$( trim "$string" )
echo -e "GIVEN STRING: |$string|\n"
echo "TRIMMED STRING: |$trimmed|"
출력:
GIVEN STRING: | wordAA
>wordB<
wordC |
TRIMMED STRING: |wordAA
>wordB<
wordC|
c) 마지막 메모:
함수를 사용하지 않으려면 한 줄 문자열에 대해 다음과 같은 "기억하기 쉬운" 명령을 사용할 수 있습니다.
echo "$string" | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'
예:
echo " wordA wordB wordC " | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'
출력:
wordA wordB wordC
위의 내용을 여러 줄의 문자열에서도 사용할 수 있지만, GuruM이 코멘트에서 지적한 바와 같이 내부 후행/선행 다중 공간도 절단된다는 점에 유의하시기 바랍니다.
string=' wordAA
>four spaces before<
>one space before< '
echo "$string" | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'
출력:
wordAA
>four spaces before<
>one space before<
이 공간을 확보해 주시면 제 답변의 선두에 있는 기능을 이용해 주십시오!
d) 함수 트림 내에서 사용되는 여러 줄 문자열의 sed 구문 "find and replace"에 대한 설명:
sed -n '
# If the first line, copy the pattern to the hold buffer
1h
# If not the first line, then append the pattern to the hold buffer
1!H
# If the last line then ...
$ {
# Copy from the hold to the pattern buffer
g
# Do the search and replace
s/^[ \t]*//g
s/[ \t]*$//g
# print
p
}'
BASH만의 다른 옵션이 몇 가지 있습니다.
line=${line##+([[:space:]])} # strip leading whitespace; no quote expansion!
line=${line%%+([[:space:]])} # strip trailing whitespace; no quote expansion!
line=${line//[[:space:]]/} # strip all whitespace
line=${line//[[:space:]]/} # strip all whitespace
line=${line//[[:blank:]]/} # strip all blank space
앞의 두 가지는extglob
priori 설정/활성화:
shopt -s extglob # bash only
메모: 따옴표 안의 변수 전개는 상위 2개의 예를 나타냅니다.
여기에서는 POSIX 괄호 식의 패턴 매칭 동작을 자세히 설명합니다.Fish 등 모던하고 해커가 가능한 셸을 사용하고 있다면 스트링 트리밍 기능이 내장되어 있습니다.
스크립트에서는 변수 할당을 사용하여 작업을 수행하는 것을 보았습니다.
$ xyz=`echo -e 'foo \n bar'`
$ echo $xyz
foo bar
공백은 자동으로 병합 및 트리밍됩니다.셸 메타캐릭터(잠재 주입 위험)에 주의해야 한다.
셸 조건에서는 항상 변수 치환을 이중 따옴표로 묶을 것을 권장합니다.
if [ -n "$var" ]; then
변수의 -o나 다른 내용 등이 테스트 인수를 수정할 수 있기 때문입니다.
공백 공간을 트리밍 및 정규화하는 trim() 함수는 다음과 같습니다.
#!/bin/bash
function trim {
echo $*
}
echo "'$(trim " one two three ")'"
# 'one two three'
정규 표현을 사용하는 다른 변종도 있습니다.
#!/bin/bash
function trim {
local trimmed="$@"
if [[ "$trimmed" =~ " *([^ ].*[^ ]) *" ]]
then
trimmed=${BASH_REMATCH[1]}
fi
echo "$trimmed"
}
echo "'$(trim " one two three ")'"
# 'one two three'
이것은 불필요한 글러빙에는 문제가 없으며 내부 화이트스페이스는 변경되지 않습니다(전제가$IFS
디폴트로 설정되어 있습니다.' \t\n'
).
첫 번째 줄 바꿈(포함되지 않음) 또는 문자열 끝(둘 중 먼저 오는 것)까지 읽고 선행 및 후행 공백의 혼합을 제거합니다.\t
성격.여러 선을 보존하려면(또한 선행 및 후행 새 선을 제거하려면)read -r -d '' var << eof
에 「」이 포함되어 있는 는, 「」가 포함되어 있는에 주의해 주세요.\neof
전에 ( 즉 ).\r
,\f
, , , , 입니다.\v
는 $IFS에 추가해도 삭제되지 않습니다.)
read -r var << eof
$var
eof
왼쪽에서 첫 번째 단어로 공백과 탭을 삭제하려면 다음과 같이 입력합니다.
echo " This is a test" | sed "s/^[ \t]*//"
cyberciti.biz/tips/delete-leading-spaces-from-front-of-each-word.html
var=' a b c '
trimmed=$(echo $var)
이것은 내가 본 것 중 가장 간단한 방법이다.Bash만 사용하고 몇 줄이며 regexp는 단순하며 모든 형식의 공백과 일치합니다.
if [[ "$test" =~ ^[[:space:]]*([^[:space:]].*[^[:space:]])[[:space:]]*$ ]]
then
test=${BASH_REMATCH[1]}
fi
테스트에 사용하는 샘플스크립트를 다음에 나타냅니다.
test=$(echo -e "\n \t Spaces and tabs and newlines be gone! \t \n ")
echo "Let's see if this works:"
echo
echo "----------"
echo -e "Testing:${test} :Tested" # Ugh!
echo "----------"
echo
echo "Ugh! Let's fix that..."
if [[ "$test" =~ ^[[:space:]]*([^[:space:]].*[^[:space:]])[[:space:]]*$ ]]
then
test=${BASH_REMATCH[1]}
fi
echo
echo "----------"
echo -e "Testing:${test}:Tested" # "Testing:Spaces and tabs and newlines be gone!"
echo "----------"
echo
echo "Ah, much better."
공백 한 개로 공백 제거:
(text) | fmt -su
할당은 선행 및 후행 공백을 무시하므로 다음과 같이 트리밍할 수 있습니다.
$ var=`echo ' hello'`; echo $var
hello
에는 Python이라는 .strip()
PHP와 합니다.trim()
따라서 간단한 인라인 Python을 사용하여 쉽게 이해할 수 있는 유틸리티를 만들 수 있습니다.
alias trim='python -c "import sys; sys.stdout.write(sys.stdin.read().strip())"'
그러면 선행 및 후행 공백(새 선 포함)이 잘립니다.
$ x=`echo -e "\n\t \n" | trim`
$ if [ -z "$x" ]; then echo hi; fi
hi
언급URL : https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-a-bash-variable
'programing' 카테고리의 다른 글
ASCII 파일 전체를 C++ std:: 문자열로 읽습니다. (0) | 2023.04.17 |
---|---|
JavaScript에서는 큰따옴표와 작은따옴표가 서로 호환됩니까? (0) | 2023.04.17 |
Excel VBA - 2D 어레이 리딤 방법 (0) | 2023.04.12 |
iOS - ViewController에서 앱 위임 메서드를 호출합니다. (0) | 2023.04.12 |
Bash에서 문자열을 배열로 분할하는 방법 (0) | 2023.04.12 |