cut -d,忽略参数中的定界符
cut -d, ignore delimiter in argument
我编写了一个获取可变数量参数的脚本:
test.sh -i <input1> <input2> ... -o <output1> <output2> ...
我正在按如下方式解析参数:
while [ $# -gt 1 ]; do
TMP=$(echo "$@" | cut -d '-' -f 2) #i <input1> <input2>
TMP1=$(echo "$TMP" | cut -d ' ' -f 1) #i
CNT=$(echo "$TMP" | wc -w) #3
set -x
case "$TMP1" in
i)
INPUTS=$(echo "$TMP" | cut -c 3-)
shift "$CNT"
;;
o)
OUTPUTS=$(echo "$TMP" | cut -c 3-)
shift "$CNT"
;;
esac
done
这每次都有效,但名称中恰好带有“-”的文件除外。
示例:
./test.sh -i file1.txt file-2.txt -o out1.txt out-2.txt
有什么办法可以强制 cut
忽略文件名中出现的分隔符?
您不需要所有这些字符串操作;每个参数已经是一个单独的词。
while (( $# > 0 )); do
case in
-i) shift
while [[ $# -gt 0 && != -* ]]; do
inputs+=( "" )
shift
done
;;
-o) shift
while [[ $# -gt 0 && != -* ]]; do
outputs+=( "" )
shift
done
;;
*) echo "Unrecognized option "
exit 1
;;
esac
done
这可以稍微重构以避免重复检查 运行 参数。
for arg in "$@"; do
case in
-i) mode=input; continue ;;
-o) mode=output; continue ;;
esac
case $mode in
input) input+=("$arg") ;;
output) output+=("$arg") ;;
*) echo "Unknown mode: $mode"
exit 1
;;
esac
done
这是一种可能对某些人有益的替代方法。
事实是,参数解析始终是一种权衡,因此根据应用程序对其进行定制是有好处的。这是一个非常通用的解决方案,允许在参数中进行一些错误检查和混乱。
很简单,但我添加了一些示例输出和注释,并且为了可读性和兼容性,远离复杂的方式来节省一两行(尤其是在 if 语句上)。
示例用法:
bash #> touch file-1 file3 file4 file-8 file7
bash #> argparse -i file-1 file3 file4 -c -k --q --j -r -t -o file-8 file7
输出:
Input files: file-1 file3 file4
Output files: file-8 file7
Args are: c k q j r t
Doing action for argument "c"
Doing action for argument "k"
Doing action for argument "j"
脚本:
#!/bin/bash
#argparse
#Assign arrays
until [[ $# < 1 ]]; do
#ignore args "-i" and "-o", and tell the script to check for files following
if [ "" == "-i" ] ; then unset output ; input=1 ; shift
elif [ "" == "-o" ] ; then unset input ; output=1 ; shift
fi
#Add input and output files to respective arrays
if [ -f "" ] ; then
if [[ $input == 1 ]]; then
infiles+=()
elif [[ $output == 1 ]]; then
outfiles+=()
fi
else
#Add args to array
arg="$(echo "" | sed 's/-//g')"
args+=($arg)
fi
shift
done
#Some debug feedback
echo -e "Input files: ${infiles[@]}\nOutput files: ${outfiles[@]}\nArgs are: ${args[@]}\n"
#Simulate actually "doing" something with the args
for arg in "${args[@]}" ; do
case $arg in
"c") echo "Doing action for argument \"c\"" ;;
"k") echo "Doing action for argument \"k\"" ;;
"j") echo "Doing action for argument \"j\"" ;;
*) ;;
esac
done
Update/Edit:我刚刚意识到,OP 对解析 actual 参数没有任何要求除了 -i
和 -o
。好吧,无论如何,这在某些时候可能仍然对某些人派上用场。
我编写了一个获取可变数量参数的脚本:
test.sh -i <input1> <input2> ... -o <output1> <output2> ...
我正在按如下方式解析参数:
while [ $# -gt 1 ]; do
TMP=$(echo "$@" | cut -d '-' -f 2) #i <input1> <input2>
TMP1=$(echo "$TMP" | cut -d ' ' -f 1) #i
CNT=$(echo "$TMP" | wc -w) #3
set -x
case "$TMP1" in
i)
INPUTS=$(echo "$TMP" | cut -c 3-)
shift "$CNT"
;;
o)
OUTPUTS=$(echo "$TMP" | cut -c 3-)
shift "$CNT"
;;
esac
done
这每次都有效,但名称中恰好带有“-”的文件除外。
示例:
./test.sh -i file1.txt file-2.txt -o out1.txt out-2.txt
有什么办法可以强制 cut
忽略文件名中出现的分隔符?
您不需要所有这些字符串操作;每个参数已经是一个单独的词。
while (( $# > 0 )); do
case in
-i) shift
while [[ $# -gt 0 && != -* ]]; do
inputs+=( "" )
shift
done
;;
-o) shift
while [[ $# -gt 0 && != -* ]]; do
outputs+=( "" )
shift
done
;;
*) echo "Unrecognized option "
exit 1
;;
esac
done
这可以稍微重构以避免重复检查 运行 参数。
for arg in "$@"; do
case in
-i) mode=input; continue ;;
-o) mode=output; continue ;;
esac
case $mode in
input) input+=("$arg") ;;
output) output+=("$arg") ;;
*) echo "Unknown mode: $mode"
exit 1
;;
esac
done
这是一种可能对某些人有益的替代方法。
事实是,参数解析始终是一种权衡,因此根据应用程序对其进行定制是有好处的。这是一个非常通用的解决方案,允许在参数中进行一些错误检查和混乱。
很简单,但我添加了一些示例输出和注释,并且为了可读性和兼容性,远离复杂的方式来节省一两行(尤其是在 if 语句上)。
示例用法:
bash #> touch file-1 file3 file4 file-8 file7
bash #> argparse -i file-1 file3 file4 -c -k --q --j -r -t -o file-8 file7
输出:
Input files: file-1 file3 file4 Output files: file-8 file7 Args are: c k q j r t Doing action for argument "c" Doing action for argument "k" Doing action for argument "j"
脚本:
#!/bin/bash
#argparse
#Assign arrays
until [[ $# < 1 ]]; do
#ignore args "-i" and "-o", and tell the script to check for files following
if [ "" == "-i" ] ; then unset output ; input=1 ; shift
elif [ "" == "-o" ] ; then unset input ; output=1 ; shift
fi
#Add input and output files to respective arrays
if [ -f "" ] ; then
if [[ $input == 1 ]]; then
infiles+=()
elif [[ $output == 1 ]]; then
outfiles+=()
fi
else
#Add args to array
arg="$(echo "" | sed 's/-//g')"
args+=($arg)
fi
shift
done
#Some debug feedback
echo -e "Input files: ${infiles[@]}\nOutput files: ${outfiles[@]}\nArgs are: ${args[@]}\n"
#Simulate actually "doing" something with the args
for arg in "${args[@]}" ; do
case $arg in
"c") echo "Doing action for argument \"c\"" ;;
"k") echo "Doing action for argument \"k\"" ;;
"j") echo "Doing action for argument \"j\"" ;;
*) ;;
esac
done
Update/Edit:我刚刚意识到,OP 对解析 actual 参数没有任何要求除了 -i
和 -o
。好吧,无论如何,这在某些时候可能仍然对某些人派上用场。