转换来自" abc"的字符串 - > " ^ A. * B. * C"在巴什

时间:2017-03-20 22:11:59

标签: bash shell

我正在调用像./test.sh abc这样的bash脚本,而"abc"参数用于^char_1.*char_2.* ... char_N形式的grep参数,其中" char_i&#34 ;是第i个输入字符的大写版本。我当前的文本文件是一个很长的完全大写单词列表,每个换行一个。

在阅读字符串操作时,我遇到了来自sed,awk,tr等程序的大量高度混乱的例子。如果我的目标只是将输入字符大写并将它们放在那个表单中,哪个Bash命令最有用,我怎样才能用该命令实现这种操作?

4 个答案:

答案 0 :(得分:4)

一个使用 bash的内置字符串操作支持的简单实现:

#!/usr/bin/env bash
#              ^^^^- NOT /bin/sh; the C-style for loop is an extension.

in=${1^^}
out='^'

for ((i=0; i<${#in}; i++)); do
  out+="${in:$i:1}.*"
done
out=${out%".*"} # trim last .*

echo "$out"

请参阅BashFAQ #100(“我如何在bash中进行字符串操作?”)以获取本机字符串操作操作的完整描述。上面使用的是:

  • ${var^^}扩展为var内容的全大写版本(请注意,这需要bash 4;对于旧版本,in=$(tr '[:lower:]' '[:upper:]' <<<"$1")是更传统的方法。)
  • ${#in}扩展为名为in的变量中的字符串长度。
  • ${varname:start:len}扩展为名为varname的变量的子字符串,从0索引位置start开始,继续len个字符。
  • ${out%".*"}扩展为$out的内容,但文字字符串.*从末尾开始修剪。 (如果它不是内部引号,.*将被视为一个模式,所以我们将删除文字字符串中最后一个.之后的所有内容,其中一个存在。)

以上也是参数扩展;它们在http://wiki.bash-hackers.org/syntax/pe详细描述。

答案 1 :(得分:0)

虽然很简陋,但awk也能做到这一点:

s='abc'

awk '{s=toupper($0); c1=substr(s,1,1); s=substr(s,2); gsub(/./, ".*&", s); print "^" c1 s}' <<< "$s"

^A.*B.*C
  • 首先,我们使用toupper函数转换为大写。
  • 我们使用substr函数将输入分为两部分,即第一个字符和休息
  • 对于其他部分,我们在.*函数
  • 中的每个字符前插入gsub
  • 最后我们连接并获得所需的格式

答案 2 :(得分:0)

为了完整起见,这里有一个sed解决方案:

sed 's/./\U&.*/g; s/^/^/; s/\.\*$//' <<<abc
^A.*B.*C

这实际上非常简单:

  • s/./\U&.*/g - 将每个字符(.)替换为自身的大写版本(\U&),后跟.*;
  • 将字符串(^)的开头替换为实际的^;
  • 使用空字符串替换行尾(.*)的文字\.\*$

答案 3 :(得分:0)

使用正则表达式的另一个 bash

[[ "${1^^}" =~ ${1//?/(.)} ]]    # to upprcase + make regex + match
b=${BASH_REMATCH[@]:1}           # join by spaces
printf -v out "^%s" "${b// /.*}" # print to var, prepend ^, replace spaces with .*

echo "$out"
#^A.*B.*C

以及pfe(perl for everything):)

perl -F// -nlE 'say uc("^".join(".*",@F))' <<< "$1"
#^A.*B.*C