Bash / Standard Linux 명령 만 사용하여 문자열에서 단일 및 이중 인용문을 제거합니다.

StackOverflow https://stackoverflow.com/questions/758031

  •  09-09-2019
  •  | 
  •  

문제

Bash / Standard Linux 명령 만 사용하여 문자열을 다음과 같이 번역 할 내용을 찾고 있습니다.

  1. 문자열을 둘러싼 단일 크기를 제거해야합니다
  2. 문자열을 둘러싼 이중 인용물을 제거해야합니다
  3. 인용되지 않은 문자열은 동일하게 유지되어야합니다
  4. 타의 추종을 불허하는 주변 인용문을 가진 줄은 동일하게 유지되어야합니다
  5. 문자열을 둘러싸고 있지 않은 단일 크기는 남아 있어야합니다
  6. 문자열을 둘러싸고 있지 않은 두 배가 남아 있어야합니다

예를 들어:

  • '음식'은 음식이되어야합니다
  • "음식"은 음식이되어야합니다
  • 음식은 동일하게 유지되어야합니다
  • '음식 "은 동일하게 유지되어야합니다
  • "음식 '은 동일하게 유지되어야합니다
  • 'fo'od'는 fo'od가되어야합니다
  • "fo'od"는 fo'od가되어야합니다
  • fo'od는 동일하게 유지되어야합니다
  • 'fo "od'는 FO"OD가되어야합니다.
  • "FO"OD "는 FO"OD가되어야합니다.
  • FO "OD는 동일하게 유지되어야합니다

고맙습니다!

도움이 되었습니까?

해결책

이렇게해야합니다.

sed "s/^\([\"']\)\(.*\)\1\$/\2/g" in.txt

in.txt는 다음과 같습니다.

"Fo'od'
'Food'
"Food"
"Fo"od'
Food
'Food"
"Food'
'Fo'od'
"Fo'od"
Fo'od
'Fo"od'
"Fo"od"
Fo"od

예상 .txt는 다음과 같습니다.

"Fo'od'
Food
Food
"Fo"od'
Food
'Food"
"Food'
Fo'od
Fo'od
Fo'od
Fo"od
Fo"od
Fo"od

당신은 그들이 일치하는 것을 확인할 수 있습니다.

diff -s <(sed "s/^\([\"']\)\(.*\)\1\$/\2/g" in.txt) expected.txt

다른 팁

당신은 사용할 수 있습니다 tr:

echo "$string" | tr -d 'chars to delete' 

... 그러나 'TR'은 훨씬 오래된 (Redhat 9-ish) 분포에 문제가있는 것으로 알려져 있습니다. tr 입력을 변환하기 위해 파이프에서 일반적으로 사용되는 '번역'에 대한 약어입니다. 그만큼 -d 옵션은 단순히 '삭제'를 의미합니다.

대부분의 최신 버전에는 미리 정의 된 매크로가 포함되어있어 상단으로, 하단으로, 하단으로, 화이트 스페이스를 죽이는 등을 포함합니다. 따라서 사용하는 경우 다른 작업을 수행하는 데 잠시 시간을 보내십시오 (도움말 출력 / 맨 페이지 참조). 편리합니다.

VAR="'FOOD'"

VAR=$(eval echo $VAR)

설명 : 인용문은 이미 쉘에 의해 이해되므로 쉘에 인용 된 문자열을 반영하는 명령을 평가할 수 있습니다.

여기, eval echo $VAR 확장됩니다 eval echo 'FOOD' 인용문은 실제로 가치의 일부이기 때문에 VAR. 당신이 달리면 echo 'FOOD' 당신이 얻을 수있는 껍질에 FOOD (인용문없이). 그게 뭐야 eval 그렇게 : 입력이 필요하고 쉘 명령처럼 실행됩니다.

code 코드 주입!

eval 스크립트를 코드 주입에 노출시킵니다.

VAR=';ls -l'

VAR=$(eval echo $VAR)

실행을 일으킬 것입니다 ls -l.

여기에는 훨씬 더 유해한 코드가 주입 될 수 있습니다.

당신은 아마 사용하고 싶을 것입니다 sed...

echo $mystring | sed -s "s/^\(\(\"\(.*\)\"\)\|\('\(.*\)'\)\)\$/\\3\\5/g"

Bash Buildins (즉, Bash 매개 변수 확장)를 사용합니다.

IFS=' ' 

food_strings=( "'Food'" '"Food"' Food "'Food\"" "\"Food'" "'Fo'od'" "\"Fo'od\"" "Fo'od" "'Fo\"od'" '"Fo"od"' 'Fo"od'  )  

for food in ${food_strings[@]}; do 

   [[ "${food#\'}" != "$food" ]] && [[ "${food%\'}" != "$food" ]] && { food="${food#\'}"; food="${food%\'}"; } 

   [[ "${food#\"}" != "$food" ]] && [[ "${food%\"}" != "$food" ]] && { food="${food#\"}"; food="${food%\"}"; } 

   echo "$food"

done 

Bash 매개 변수 확장의 또 다른 예는 다음을 참조하십시오.

http://codesnippets.joyent.com/posts/show/1816

이것도 우연히 발견했습니다. 처음 세 가지 테스트 사례의 경우 eval echo $string 잘 작동합니다. 요청 된 모든 사례와 다른 몇 가지 사례에 대해 작동하도록하기 위해 나는 이것을 생각해 냈습니다 (테스트. bash 그리고 dash):

#!/bin/sh

stripquotes() {
    local firstchar="`substr "$1" 0 1`"
    local len=${#1}
    local ilast=$((${#1} - 1))
    local lastchar="`substr "$1" $(($len - 1))`"
    if [ "$firstchar" = '"' ] || [ "$firstchar" = "'" ] && [ $firstchar = $lastchar ]; then
        echo "`substr "$1" 1 $(($len - 2))`"
    else
        echo "$1"
    fi
}

# $1 = String.
# $2 = Start index.
# $3 = Length (optional). If unspecified or an empty string, the length of the
#      rest of the string is used.
substr() {
    local "len=$3"
    [ "$len" = '' ] && len=${#1}
    if ! (echo ${1:$2:$len}) 2>/dev/null; then
        echo "$1" | awk "{ print(substr(\$0, $(($2 + 1)), $len)) }"
    fi
}

var="'Food'"
stripquotes "$var"

var='"Food"'
stripquotes "$var"

var=Food
stripquotes "$var"

var=\'Food\"
stripquotes "$var"

var=\"Food\'
stripquotes "$var"

var="'Fo'od'"
stripquotes "$var"

var="\"Fo'od\""
stripquotes "$var"

var="Fo'od"
stripquotes "$var"

var="'Fo\"od'"
stripquotes "$var"

var="\"Fo\"od\""
stripquotes "$var"

var="Fo\"od"
stripquotes "$var"

# A string with whitespace should work too.
var="'F\"o 'o o o' o\"d'"
stripquotes "$var"

# Strings that start and end with the same character that isn't a quote or
# doublequote should stay the same.
var="TEST"
stripquotes "$var"

# An empty string should not cause errors.
var=
stripquotes "$var"

# Strings of length 2 that begin and end with a quote or doublequote should not
# cause errors.
var="''"
stripquotes "$var"
var='""'
stripquotes "$var"
python -c "import sys;a=sys.stdin.read();a=a.strip();print (a[1:-1] if a[0]==a[-1] and a[0] in \"'\\\"\" else a)"

Edge Case를 매우 잘 처리하지는 않지만 (예 : 빈 문자열과 같은) 출발점 역할을합니다. 동일하고 '또는'인 경우 전면 및 후면 문자를 스트라이핑하여 작동합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top