3 Stimmen

Filtern von Zeilen anhand von Spaltenwerten in Bash

Ich habe ein Bash-Skript, das einige spaltenbasierte Informationen ausgibt. Ich möchte dem Benutzer einige Optionen zum Abgleichen von Werten in bestimmten Spalten geben. Zum Beispiel, ./myColumnDump könnte drucken

User Job\_name Start\_day
andrew job1\_id monday
andrew job2\_id tuesday
adam job1\_id tuesday
adam job2\_id monday

und ich würde gerne Optionen hinzufügen wie ./myColumDump -j 2 (wobei das Argument j ein regulärer Ausdruck ist, der auf Werte in der Spalte Job_name passt).

Ich bin derzeit Piping die Ausgabe durch grep und Einbetten der benutzerdefinierten Regex in eine große Regex, um eine ganze Zeile übereinstimmen, aber die he/she könnte angeben -j .*monday die in die andere Spalte überlaufen würden.

Gibt es einen schöneren Weg, um dies in einem Bash-Skript zu erreichen?

3voto

mu is too short Punkte 411765

Dieses Problem ist wie geschaffen für awk (1) . Sie können zum Beispiel so vorgehen:

awk '$2 ~ /^job1/'

um Zeilen auszudrucken, in denen Spalte zwei übereinstimmt ^job1 . Wenn also eine Spaltennummer in N und einem regulären Ausdruck in R sollten Sie in der Lage sein, dies zu tun:

awk "\$${N} ~ /${R}/"

Wie üblich müssen Sie bei der Zitierung vorsichtig sein.

2voto

glenn jackman Punkte 221248

Aufbauend auf mu ist zu kurz Wenn Sie die Antwort von awk kennen, können Sie das Muster des Benutzers an awk übergeben:

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

Sie müssen den Benutzern jedoch raten, ein Regex-Muster einzugeben, das awk versteht.

2voto

anubhava Punkte 713155

Hier ist das vollständige Bash-Skript scan.sh, um Ihre Arbeit zu erledigen:

#!/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}"

TESTING

Nehmen wir an, dies ist Ihre Datendatei: Benutzer Job_name Start_tag

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

2voto

bash-o-logist Punkte 6407

Hier ist ein reines Bash-Skript (mit freundlicher Genehmigung von anubhava)

#!/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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X