已经发布的使用 awk 或 sed 的解决方案是非常标准的,如果某些事情无法正常工作,它会有所帮助。
比如:
StringStr="ValueA:ValueB,ValueC:ValueC" ;
echo ${StringStr} | gawk -F',' 'BEGIN{}{for(intx=1;intx<=NF;intx++){printf("%sn",$(intx))}}END{}'
确实会产生相同的结果,但是可以登录其帐户并且具有较少选项(例如由于特定原因不允许使用awk或gawk)的受限用户确实必须生成每次都必须工作的东西。
出于有效的原因,我确实在 github.com 上开发了自己的 Bash 函数库,并使用了一种无法按预期工作的技术,这里有一个工作示例:
此技术使用 Bash "删除匹配的前缀模式"和"删除匹配的后缀模式"。目标是获取一串链接信息,以使用尽可能简单的 bash-shell 元素来提取插入的元素。
到目前为止,我确实有第一个语句来获取特定格式的字符串: 前任:
StringPattern="__VALUE1__:__VALUE2__,"
该格式假设在链中添加许多类型为字符串模式的模式。 剩下的 '","' 将用于拆分和分离字符串 值1:值 2形式 .
像 StringStorage 会持有很多次,解析 StringPattern,这里有 2 个例子: 1 - 样本 1
StringPattern="VariableA:InformationA,"
StringStorage="${StringStorage}${StringPattern}" ;
2 - 样本 2
StringPattern="VariableB:InformationB,"
StringStorage="${StringStorage}${StringPattern}" ;
此时,StringStorage 正确保存此信息:
StringStorage="VariableA:InformationA,VariableB:InformationB,"
现在有了 StringStorage,由"删除匹配前缀模式"和"删除匹配后缀模式"混合组成的 bash 算法确实适用于这种情况:
### Description of IntCsvCount
### does remove all chosed Comma Separated value ',' from StringStorage
### and subtract from the original length the removed result from this
### subtraction. This produce IntCsvCount == 2
IntCsvCount=$( cstr=${StringStorage//,/} ; echo $(( ${#StringStorage} - ${#cstr} )) ) ;
### Description of
### Will be re Variable used to put the Extracted sequence.
bstr="" ;
### Description of for
### Received information from IntCsvCount it should count
### from 0 to Last element . This case it's ${IntCsvCount}-1 or 1 in
### my example.
for (( intx=0 ; intx <= ${IntCsvCount}-1 ; intx++ )) ; do
### This extracting First Segment based on
### Remove matching suffix pattern ${parameter%word} where
### work is ${astr#*,} ( Remove matching prefix pattern ) of
### everything in $astr until find a ',' .
bstr=${astr%*${astr#*,}} ;
### Destroying the $bstr part in by starting the astr to position of
### the end of size equivalent of bstr size (${#bstr}), end position is
### equal to [ Highest-String size ] - [ Shortest-String size ]
astr=${astr:${#bstr}:$(( ${#astr} - ${#bstr}))} ;
echo -ne "Element: ${bstr}n" ;
done
这应该产生以下答案。
Element: VariableA:InformationA,
Element: VariableB:InformationB,
将其放入函数中只需要将CSV更改为":",并提取"变量A"和"信息A"。
问题开始使用非均匀字符串。正如在这块板上观察到的,一个句子的例子和一个部分应该适用于不均匀的字符串,但这里的样本不起作用。而且我手头确实有不止一个关于使用 gawk、sed 甚至切割的建议,但从这个算法来看,它不适用于这个样本:
astr="master|ZenityShellEval|Variable declaration|Added Zenity font support to allow choosing both font-name and size and parsing the zenition option, notice --font option require a space between font and size.|20170127|"
来自
astr=$( zenity --width=640 --height=600 --forms --show-header --text="Commit Message" --add-entry="Branch name" --add-entry="function" --add-entry="section" --add-entry="commit Message" --add-calendar="Commit Date" --forms-date-format="%Y%m%d" --separator='|' ) ;
我还强制输出看起来像 StringPattern 应该是什么样子: astr="${astr}|" ;
除 CSV(逗号分隔值)外的相同代码已从","更改为"|">
IntCsvCount=$( cstr=${astr//|/} ; echo $(( ${#astr} - ${#cstr} )) ) ;
bstr="" ;
for (( intx=0 ; intx <= ${IntCsvCount}-1 ; intx++ )) ; do
bstr=${astr%*${astr#*|}} ;
astr=${astr:${#bstr}:$(( ${#astr} - ${#bstr}))} ;
echo -ne "Element: ${bstr}n" ;
done
其中,此时间输出生成以下输出:
Element:master|ZenityShellEval|Variable declaration|Added Zenity font support to allow choosing both font-name and size and parsing the zenition option, notice --font option require a space between font and size.|20170127|
Element:
Element:
Element:
有什么原因为什么它不应该每次都工作吗?
所以,你发布了这个AWK脚本:
BEGIN{}{for(intx=1;intx<=NF;intx++){printf("%sn",$(intx))}}END{}
如果我理解正确,你是说它完全符合您的要求,唯一的问题是您不想依赖 AWK?
在这种情况下,您实际上使这比您需要的更复杂。你可以直接使用 Bash 的子字符串替换功能:
str=ValueA:ValueB,ValueC:ValueC
printf '%sn' "${str//,/$'n'}"
如果我正确理解了您问题的结尾,那么您有一个类似astr="master|ZenityShellEval|Variable declaration|Added Zenity font support to allow choosing both font-name and size and parsing the zenition option, notice --font option require a space between font and size.|20170127|"
的字符串,并且您需要以下输出:
Element: master
Element: ZenityShellEval
Element: Variable declaration
Element: Added Zenity font support to allow choosing both font-name and size and parsing the zenition option, notice --font option require a space between font and size.
Element: 20170127
我能想到的最简单的方法如下:
s="${astr%|}"; echo "Element: ${s//|/$'n'Element: }";
另外,不要忘记数组!我认为它们会派上用场,用于您正在做的事情。以下内容还会生成所需的输出:
(IFS='|'; declare -a a=(${astr}); printf "Element: %sn" "${a[@]}")
Bash Hackers Wiki有一个关于数组的很棒的页面,我建议查看一下。
这是对最后几个主题的相同运行:
IFS="|" read -ra arr<<<"${astr}"
printf "Element: %sn" "${arr[@]}"
我想我会补充一点,你原来的awk有点臃肿:
echo -n "ValueA:ValueB,ValueC:ValueC" | awk '1' RS=","
当然,当前解决方案的awk:
awk 'NF && $0 = "Element: " $0' RS="|" <<<"$astr"