Удаление одинарных и двойных кавычек в строке только с помощью команд Bash / standard Linux
Я ищу что-то, что переведет строку следующим образом, используя только команды bash / standard Linux:
- одинарные кавычки вокруг строки должны быть удалены
- двойные кавычки, окружающие строку, должны быть удалены
- строки без кавычек должны оставаться неизменными
- строки с непревзойденными окружающими кавычками должны оставаться неизменными
- одинарные кавычки, которые не окружают строку, должны останься
- двойные кавычки, которые не окружают строку, должны оставаться
например:
- " еда " должна стать едой
- "еда" должна стать еда
- еда должна оставаться прежней
- " еда " должна оставаться прежней
- "еда" должна оставаться прежней
- 'FO'od' должен стать Fo'od
- "fo'od" должен стать Fo'od
- fo'od должен оставаться же
- ' Fo " od 'должен стать Fo" od
- "Fo" od "должно стать Fo" od
- FO " od должен оставаться тем же
спасибо!
7 ответов
это должно сделать это:
sed "s/^\([\"']\)\(.*\)$//g" in.txt
где в.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/^\([\"']\)\(.*\)$//g" in.txt) expected.txt
вы могли бы использовать tr
:
echo "$string" | tr -d 'chars to delete'
... также работает, однако "tr", как известно, проблематичен на гораздо более старых (около Redhat 9-ish) дистрибутивах. tr
- это аббревиатура для "translate", обычно используемая в трубах для преобразования входных данных. The просто означает "удалить".
большинство современных версиях также содержат стандартные макросы для преобразования верх-низ, низ-верх, убить белого пространства и т. д. Следовательно, если вы используете его, потратьте секунду, чтобы ткнуть в то, что еще это делает (см. справку / man-страницу), пригодится.
VAR="'FOOD'"
VAR=$(eval echo $VAR)
объяснение: поскольку кавычки уже понятны оболочке, вы можете попросить оболочку оценить команду, которая просто повторяет цитируемую строку, так же, как и при вводе ее самостоятельно.
здесь eval echo $VAR
увеличивается до eval echo 'FOOD'
потому что кавычки на самом деле являются частью значения VAR
. Если бы ты побежал echo 'FOOD'
в оболочку вы получите FOOD
(без кавычек). Вот что!--6--> does: он принимает свой ввод и запускает его как команду оболочки.
вы, вероятно, хотите использовать sed...
echo $mystring | sed -s "s/^\(\(\"\(.*\)\"\)\|\('\(.*\)'\)\)$/\3\5/g"
просто используя bash builtins (т. е. расширение параметра 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 см. В разделе:
просто наткнулся на это. Для первых трех тестовых случаев eval echo $string
работает хорошо. Чтобы заставить его работать для всех запрошенных случаев и нескольких других, я придумал это (протестировано с bash
и dash
):
#!/bin/sh
stripquotes() {
local firstchar="`substr "" 0 1`"
local len=${#1}
local ilast=$((${#1} - 1))
local lastchar="`substr "" $(($len - 1))`"
if [ "$firstchar" = '"' ] || [ "$firstchar" = "'" ] && [ $firstchar = $lastchar ]; then
echo "`substr "" 1 $(($len - 2))`"
else
echo ""
fi
}
# = String.
# = Start index.
# = Length (optional). If unspecified or an empty string, the length of the
# rest of the string is used.
substr() {
local "len="
[ "$len" = '' ] && len=${#1}
if ! (echo ${1::$len}) 2>/dev/null; then
echo "" | awk "{ print(substr($0, $(( + 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)"
он не очень хорошо обрабатывает крайние случаи (например, пустую строку), но он будет служить отправной точкой. Он работает, чередуя передний и задний символ, если они одинаковы, и если они "или"