基于Bash中的列值筛选行

基于Bash中的列值筛选行,bash,text-processing,Bash,Text Processing,我有一个bash脚本,它输出一些基于列的信息。我想给用户一些选项来匹配特定列的值。例如,/myColumnDump可能会打印 User Job_name Start_day andrew job1_id monday andrew job2_id tuesday adam job1_id tuesday adam job2_id monday 用户作业名称开始日 安德鲁·乔布,星期一 安德鲁·乔布星期二 亚当·乔布星期二 亚当·乔布,星期一 我想添加一些选项,比如/myclumdump-j2(其

我有一个bash脚本,它输出一些基于列的信息。我想给用户一些选项来匹配特定列的值。例如,
/myColumnDump
可能会打印

User Job_name Start_day andrew job1_id monday andrew job2_id tuesday adam job1_id tuesday adam job2_id monday 用户作业名称开始日 安德鲁·乔布,星期一 安德鲁·乔布星期二 亚当·乔布星期二 亚当·乔布,星期一 我想添加一些选项,比如
/myclumdump-j2
(其中j的参数是一个正则表达式,用于匹配Job_name列中的值)

我目前正在通过grep管道输出,并将用户指定的正则表达式嵌入到一个大正则表达式中,以匹配整行,但他/她可能会指定
-j.*monday
,这将溢出到不同的列中


在bash脚本中有没有更好的方法来实现这一点?

这个问题是专门为之设计的。例如,您可以执行以下操作:

awk '$2 ~ /^job1/'
打印列2与
^job1
匹配的行。因此,给定
N
中的列号和
R
中的正则表达式,您应该能够执行以下操作:

awk "\$${N} ~ /${R}/"
与往常一样,您需要小心引用。

要在mu的答案过于简短的基础上构建,您可以将用户的模式传递给awk:

# suppose the -j pattern is in shell var $j
awk -v j="$j" '$2 ~ j'

必须建议用户输入awk理解的正则表达式模式。

以下是完成工作的完整bash脚本scan.sh:

#!/bin/bash
usage()
{
cat << EOF
usage: $0 options
This script scans given input file for specified regex in the input column #   
OPTIONS:
   -h      Show usage instructions
   -f      input data file name
   -r      regular expression to match
   -j      column number
EOF
}   
# process inputs to the script
DATA_FILE=
COL_NUM=
REG_EX=
while getopts ":j:f:r:h" OPTION
do
     case $OPTION in
         f) DATA_FILE="$OPTARG" ;;
         r) REG_EX="$OPTARG" ;;
         j) COL_NUM="$OPTARG" ;;
         \?) usage
             exit 1 ;;
         h)
             usage
             exit 1 ;;
     esac
done   
if [[ -z $DATA_FILE ]] || [[ -z $COL_NUM ]] || [[ -z $REG_EX ]]
then
     usage
     exit 1
fi

awk -v J=${COL_NUM} -v R="${REG_EX}" '{if (match($J, R)) print $0;}' "${DATA_FILE}"
这是一个纯bash脚本(由anubhava提供)

#/bin/bash
#在Bash4上测试
用法()
{
猫
andrew job1_id monday
andrew job2_id tuesday
adam job1_id tuesday
adam job2_id monday

./scan.sh -j 2 -f data  -r ".*job1.*"
andrew job1_id monday
adam job1_id tuesday

./scan.sh -j 2 -f data  -r ".*job2.*"
andrew job2_id monday
adam job2_id tuesday

./scan.sh -j 1 -f data  -r ".*adam.*"
adam job1_id tuesday
adam job2_id monday
#!/bin/bash
# tested on bash 4
usage()
{
cat << EOF
usage: $0 options [file]
This script scans given input file for specified regex in the input column #
OPTIONS:
   -h      Show usage instructions
   -f      input data file name
   -r      regular expression to match
   -j      column number

Example:  $0 -j 2 -r "job2" -f file
EOF
}
# process inputs to the script
DATA_FILE=
COL_NUM=
REG_EX=
while getopts ":j:f:r:h" OPTION
do
     case $OPTION in
         f) DATA_FILE="$OPTARG" ;;
         r) REG_EX="$OPTARG" ;;
         j) COL_NUM="$OPTARG" ;;
         \?) usage
             exit 1 ;;
         h)
             usage
             exit 1 ;;
     esac
done
if [[ -z $DATA_FILE ]] || [[ -z $COL_NUM ]] || [[ -z $REG_EX ]]
then
     usage
     exit 1
fi
while read -r line
do
    array=( $line )
    col=${array[$((COL_NUM-1))]}
    [[ $col =~ $REG_EX ]] && echo "$line"
done < $DATA_FILE