1

我想用 awk 将一个 var 拆分两次,这就是我到目前为止所得到的。

awk -v p=1,3,8,25-27,4-16 '{split(p,t,",");for (i in t) if(t[i] ~ /-/) split(t[i],t1,"-") {print "-dFirstPage=" t1[1] ,"-dFirstPage=" t1[2]} ELSE {print "-dFirstPage=" t[i] ,"-dFirstPage=" t[i]}}' >outfile

输出应为

-dFirstPage=1 -dLastPage=1
-dFirstPage=3 -dLastPage=3
-dFirstPage=8 -dLastPage=8
-dFirstPage=25 -dLastPage=27
-dFirstPage=4 -dLastPage=16
4

5 回答 5

1

bash

#!/bin/bash

vars=1,3,8,25-27,4-16

for pages in `echo $vars | tr ',' '\n'`; do
    if [[ -n $( echo $pages | grep --only-matching "-" ) ]]; then
        firstPage=`echo ${pages%%-*}`
        lastPage=`echo ${pages##*-}`
    else
        firstPage=$pages
        lastPage=$pages
    fi
    echo "-dFirstPage=${firstPage} -dLastPage=${lastPage}"
done

输出:

-dFirstPage=1 -dLastPage=1
-dFirstPage=3 -dLastPage=3
-dFirstPage=8 -dLastPage=8
-dFirstPage=25 -dLastPage=27
-dFirstPage=4 -dLastPage=16

应用一些@shellter 的建议:

#!/bin/bash

vars=1,3,8,25-27,4-16
for pages in `echo $vars | tr ',' '\n'`; do
    case $pages in
        *-* )
            firstPage=${pages%%-*}
            lastPage=${pages##*-}
            ;;
        * )
            firstPage=$pages
            lastPage=$pages
            ;;
    esac
    echo "-dFirstPage=${firstPage} -dLastPage=${lastPage}"
done
于 2012-06-05T14:06:17.923 回答
1

您可以将 的值p作为输入传递给 awk 吗?在这种情况下,我会这样做:

$ echo 1,3,8,25-27,4-16 | awk -F- -v RS=, '{printf "-dFirstPage=%s -dLastPage=%s\n", $1, $2?$2:$1}'
-dFirstPage=1 -dLastPage=1
-dFirstPage=3 -dLastPage=3
-dFirstPage=8 -dLastPage=8
-dFirstPage=25 -dLastPage=27
-dFirstPage=4 -dLastPage=16

这是如何工作的:

  • 我定义逗号将是记录分隔符 ( -v RS=,),连字符将是字段分隔符 ( -F-)。所以,输入

    1,3,8,25-27,4-16
    

    将大致相当于

    1
    3
    8
    25 27
    4 16
    
  • 然后,我使用printf

    '{printf "-dFirstPage=%s -dLastPage=%s\n", $1, $2?$2:$1}'
    

    第一个参数是第一列。在第二个参数中,我询问第二列是否$2存在;如果是,那么参数的值为$2; 如果否,则值为第一列$1

于 2012-06-05T14:43:41.997 回答
1

非常接近:

awk -v p=1,3,8,25-27,4-16 'BEGIN {split(p,t,",");for (i in t) if(t[i] ~ /-/) {split(t[i],t1,"-"); print "-dFirstPage=" t1[1] ,"-dFirstPage=" t1[2]} else {print "-dFirstPage=" t[i] ,"-dFirstPage=" t[i]}}' >outfile
  • 使用BEGIN子句
  • 将“其他”更改为else
  • 将大括号从第一个之前移动print到之前,split并在它所在的位置放置一个分号
于 2012-06-05T16:44:11.237 回答
1

你离得很近,(但我不确定这个解决方案是否真的能满足你的最终要求)。

 awk -v p=1,3,8,25-27,4-16 '
 END{
        split(p,t,",");
  for (i in t) {
    if(t[i] ~ /-/) {
        split(t[i],t1,"-");
      print "-dFirstPage=" t1[1] ,"-dFirstPage=" t1[2]
    }
    else {
      print "-dFirstPage=" t[i] ,"-dFirstPage=" t[i]
    }
  }
}' /dev/null > outfile

针对 windows 和更通用的解决方案进行了修订

 echo "1,3,8,25-27,4-16" \
 | awk '
 {
   split($0,t,",");
   for (i in t) {
     if(t[i] ~ /-/) {
        split(t[i],t1,"-");
        print "-dFirstPage=" t1[1] ,"-dFirstPage=" t1[2]
     }
     else {
       print "-dFirstPage=" t[i] ,"-dFirstPage=" t[i]
     }
   }
 }' > outfile

如果需要澄清,请随时编辑您的问题。

我希望这有帮助。

于 2012-06-05T14:00:49.373 回答
1

你所需要的只是:for、echo、if

如果你必须做数千次,速度会快很多倍

vars=1,3,8,25-27,4-16
f='-dfirstpage='
l='-dlastpage='

for pages in ${vars//,/ }; do
   if [[ -n ${pages//[[:digit:]]/} ]]; then
      echo "${f}${pages%%-*} ${l}${pages##*-}"
   else
      echo "${f}${pages} ${l}${pages}"
   fi
done

输出

-dFirstPage=1 -dLastPage=1
-dFirstPage=3 -dLastPage=3
-dFirstPage=8 -dLastPage=8
-dFirstPage=25 -dLastPage=27
-dFirstPage=4 -dLastPage=16
于 2018-05-09T15:11:14.910 回答