对shell脚本中使用的每个字符串执行操作

时间:2014-03-22 20:05:51

标签: macos bash shell

问题

我想在shell脚本(bin / bash)中使用的字符串的每个字母上执行命令。在下面提到的情况下,我将发送中文字符到" $ @"输入但字符串中没有空格和分隔符。我正在考虑使用字符串长度,然后访问字符串中每个地方的索引:这是我到目前为止所做的(注意rdef是我创建的自定义命令)

PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin/: 
export PATH
for f in "$@"
do
    //need to loop through the input and perform action on each index of the $f variable
    rdef "$f"|awk -F '\|' '{ gsub(/^ +| +$/, "", $2); print $2 }'
done

rdef的标准输入:

rdef 快乐

rdef的标准输出:

Definition of <快乐>: | kuài lè |
happy
merry

更新

虽然另一个问题是类似的,但它不是同一个背景。例如,在这种情况下,我需要将作为参数传入脚本的字符串拆分。我还需要将拆分字符串应用于一组链式命令。所有这些都表示相关问题中未涉及的细微差别。

我尝试过以下代码,这些代码似乎不适用于中文字符。当我插入ASCII字符时,命令执行并返回正确的结果。

PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin/: 
export PATH


for f in "$@"

do
    foo="$f"

    for (( i=0; i<${#foo}; i++ )); do
        rdef ${foo:$i:1}|awk -F '\|' '{ gsub(/^ +| +$/, "", $2); print $2 }'
    done

done

NB:

我的最终命令行应该允许我在每个字母上执行链接到awk的自定义命令:

rdef "$letter-var"|awk -F '\|' '{ gsub(/^ +| +$/, "", $2); print $2 }'

有关rdef的更多信息,请访问以下操作系统question

解决方案

所提供的所有解决方案都运作良好。我选择了@kojiro提供的选项,因为他指出了正确的方向,需要UTF-8。这是一个重要的发现,因为汉字的双字节性质正在破坏循环的执行。

PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin/: 
export PATH
LC_CTYPE=UTF-8
x=$1

for ((i=0;i<${#x};i++)); do rdef "${x:i:1}" | awk -F '\|' '{ gsub(/^ +| +$/, "", $2); print $2 }'; done

4 个答案:

答案 0 :(得分:2)

Bash 4内置了子串切片:

$ x='红楼梦'
$ for ((i=0;i<${#x};i++)); do echo "${x:i:1}"; done
红
楼
梦

答案 1 :(得分:1)

您可以使用awk在每个字母上执行命令。

echo "XXXXX" \
| awk -v FS="" '{ for( I=1 ; I <= NF ; I++ ){ system( "command " $I ) } }
  • FS =&#34;&#34;告诉awk每个字符都是一个单独的字段。
  • for循环遍历字符并执行命令。
  • 您需要将命令替换为您要执行的命令。

例如:

echo "いい天気ですね " \
| awk -v FS="" '{ for( I=1 ; I <= NF ; I++ ){ system( "echo \"x" $I "x\"" ) } }'

将显示:

xいx
xいx
x天x
x気x
xでx
xすx
xねx
x x

您需要一个支持多字节字符的awk。

答案 2 :(得分:1)

您也可以使用perl

perl -C -lnE 'say for split //' <<<"红楼梦"

打印

红
楼
梦

答案 3 :(得分:1)

您可以使用sed添加缺少的空格,这将使您的for循环迭代每个字符:

for f in $( echo "$*" | sed -e 's/\(.\)/\1 /g' )
do
  ...
done