Command-Line

如何建構一個長命令字元串?

  • January 26, 2019

我有一系列命令與大量管道一起使用,如下所示:

awk '{ if ($8 ~ "isad") {print $2, $5, "SE"} else {print $2, $5, "ANT"} }' "/var/log/apache2/other_vhosts_access.log" | grep -v '127.0.0.1' | tr '[' '\0' | tr [:lower:] [:upper:] | sort -t' ' -s -k3

這基本上過濾了 Apache 日誌並列印了三列資訊。第一個 col 是 IP 地址,第二個是時間,第三個是字元串。可以根據任何列對輸出進行排序,因此,我需要對時間欄位使用“-m”和排序。排序順序也可以顛倒。

我想要一個字元串來儲存要排序的參數,並讓組合的字元串得到執行。像這樣的東西:

$AWK_CMD | $SORT_CMD $SORT_KEY $SORT_REV

在哪裡

SORT_CMD="sort -t' '"
SORT_KEY="-k$1"      # $1 from cmd line arg
SORT_REV="$2"        # Either -r or blank

能夠建構這樣的字元串;當我回應它時,它看起來很好。問題是,如何執行?我收到一些錯誤,例如:

awk '{ if ($8 ~ "isad") {print $2, $5, "SE"} else {print $2, $5, "ANT"} }' "/var/log/apache2/other_vhosts_access.log" | grep -v '127.0.0.1' | tr '[' '\0' | tr [:lower:] [:upper:] | sort -t' ' -s -k3
Running ...
awk: '{
awk: ^ invalid char ''' in expression

如果“排序”沒有正確排序,請忽略,這可以修復。我想知道如何逐步建構最終的命令字元串。我嘗試在腳本中執行此命令的方式是:

$final_cmd
`$final_cmd`

編輯:我正在嘗試使用的腳本

KEY=$1      # Values {1, 2, 3}
REVERSE=$2  # Values {0, 1} 

SORT_CMD="sort -t' ' -s"
SORT_KEY="-k$KEY"
if [[ $KEY -eq 2 ]]
then
   SORT_KEY="-m -k2"
fi

if [[ $REVERSE -eq 1 ]]
then
   SORT_REV="-r"
else
   SORT_REV=
fi

final_cmd="awk '{ if (\$8 ~ \"isad\") {print \$2, \$5, \"SE\"} else {print \$2, \$5, \"ANT\"} }' $LOG_FILE '|' grep -v '127.0.0.1' '|' tr '[' '\0' '|' tr [:lower:] [:upper:] '|' $SORT_CMD $SORT_KEY $SORT_REV"

echo $final_cmd
echo "Running ..."
$final_cmd

不同的部分可以放在 shell 函式中:

awkfilter() {
   awk '{ if ($8 ~ "isad") {print $2, $5, "SE"} else {print $2, $5, "ANT"} }'
}

toupper() {
   tr '[:lower:]' '[:upper:]'
}

dosort() {
   sort -t' ' -s -k3
}

awkfilter < /var/log/apache2/other_vhosts_access.log |
 grep -vF 127.0.0.1 |
 tr '[' '\0' |
 toupper |
 dosort

那麼您可以更輕鬆地使事情變得可選:

dosort() {
   rev=
   if [ "$2" = "reverse" ]
   then
       rev=-r
   fi
   sort -t' ' -s -k"$1" ${rev+"$rev"}
}

當您的命令行開始變得很長時,將其寫入腳本並將其分成幾部分(使用函式)通常會很有幫助。

引用自:https://unix.stackexchange.com/questions/7627